Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 2,436 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Claim Rewards | 21106547 | 40 hrs ago | IN | 0 ETH | 0.0019569 | ||||
Deposit | 21106504 | 40 hrs ago | IN | 0 ETH | 0.00134255 | ||||
Stake Rewards | 21106198 | 41 hrs ago | IN | 0 ETH | 0.00126078 | ||||
Stake Rewards | 21106187 | 41 hrs ago | IN | 0 ETH | 0.00121713 | ||||
Stake Rewards | 21103816 | 2 days ago | IN | 0 ETH | 0.00266585 | ||||
Withdraw And Cla... | 21102336 | 2 days ago | IN | 0 ETH | 0.00115427 | ||||
Claim Rewards | 21102331 | 2 days ago | IN | 0 ETH | 0.00080501 | ||||
Stake Rewards | 21102329 | 2 days ago | IN | 0 ETH | 0.00059887 | ||||
Stake Rewards | 21102319 | 2 days ago | IN | 0 ETH | 0.00054955 | ||||
Stake Rewards | 21102315 | 2 days ago | IN | 0 ETH | 0.00057659 | ||||
Deposit | 21101818 | 2 days ago | IN | 0 ETH | 0.00327511 | ||||
Stake Rewards | 21098430 | 2 days ago | IN | 0 ETH | 0.00245413 | ||||
Stake Rewards | 21098409 | 2 days ago | IN | 0 ETH | 0.00247323 | ||||
Stake Rewards | 21098394 | 2 days ago | IN | 0 ETH | 0.00244795 | ||||
Stake Rewards | 21098391 | 2 days ago | IN | 0 ETH | 0.00274775 | ||||
Stake Rewards | 21098368 | 2 days ago | IN | 0 ETH | 0.00276184 | ||||
Claim Rewards | 21098086 | 2 days ago | IN | 0 ETH | 0.00170938 | ||||
Withdraw And Cla... | 21093808 | 3 days ago | IN | 0 ETH | 0.00389751 | ||||
Claim Rewards | 21093707 | 3 days ago | IN | 0 ETH | 0.0023277 | ||||
Stake Rewards | 21090832 | 3 days ago | IN | 0 ETH | 0.00113318 | ||||
Claim Rewards | 21084391 | 4 days ago | IN | 0 ETH | 0.00124253 | ||||
Stake Rewards | 21078570 | 5 days ago | IN | 0 ETH | 0.00248646 | ||||
Stake Rewards | 21078555 | 5 days ago | IN | 0 ETH | 0.00216462 | ||||
Claim Rewards | 21078286 | 5 days ago | IN | 0 ETH | 0.00374255 | ||||
Withdraw And Cla... | 21078105 | 5 days ago | IN | 0 ETH | 0.00194686 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
Staking
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 800 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol"; import "@openzeppelin/contracts/utils/Counters.sol"; import "./interfaces/ITreasury.sol"; import "./interfaces/IHelix.sol"; import "./interfaces/IKondux.sol"; import "./interfaces/IKonduxERC20.sol"; import "./types/AccessControlled.sol"; contract Staking is AccessControlled { using Counters for Counters.Counter; Counters.Counter private _depositIds; /** * @dev Struct representing a staker's information. */ struct Staker { // The address of the staked token address token; // The address of the staker address staker; // The total amount of tokens deposited by the staker uint256 deposited; // The total amount of tokens redeemed by the staker uint256 redeemed; // The timestamp of the last update for this staker's deposit uint256 timeOfLastUpdate; // The timestamp of the staker's last deposit uint256 lastDepositTime; // The accumulated, but unclaimed rewards for the staker. These are calculated // each time a user writes to the contract uint256 unclaimedRewards; // The duration of the timelock applied to the staker's deposit uint256 timelock; // The category of the timelock applied to the staker's deposit uint8 timelockCategory; // ERC20 Ratio at the time of staking uint256 ratioERC20; } enum LockingTimes { OneMonth, // 0 ThreeMonths, // 1 SixMonths, // 2 OneYear // 3 } // The deposit IDs associated with a user's address mapping(address => uint[]) public userDepositsIds; // The Staker struct information associated with a deposit ID mapping(uint => Staker) public userDeposits; // Indicates whether a specific ERC20 token is authorized for staking mapping (address => bool) public authorizedERC20; // The minimum amount required to stake for a specific ERC20 token mapping (address => uint256) public minStakeERC20; // The compound frequency for a specific ERC20 token mapping (address => uint256) public compoundFreqERC20; // The rewards per hour for a specific ERC20 token mapping (address => uint256) public aprERC20; // The withdrawal fee for a specific ERC20 token mapping (address => uint256) public withdrawalFeeERC20; // The founders reward boost for a specific ERC20 token mapping (address => uint256) public foundersRewardBoostERC20; // The kNFT reward boost for a specific ERC20 token mapping (address => uint256) public kNFTRewardBoostERC20; // The ratio for a specific ERC20 token mapping (address => uint256) public ratioERC20; // The decimals of a specific ERC20 token mapping (address => uint8) public decimalsERC20; // The total amount staked for a specific ERC20 token mapping (address => uint256) public totalStaked; // The total amount staked by a user for a specific ERC20 token mapping (address => mapping (address => uint256)) public userTotalStakedByCoin; // The total amount rewarded for a specific ERC20 token mapping (address => uint256) public totalRewarded; // The total amount rewarded by a user for a specific ERC20 token mapping (address => mapping (address => uint256)) public userTotalRewardedByCoin; // The total amount paid as a withdrawal fee for a specific ERC20 token mapping (address => uint256) public totalWithdrawalFees; // The penalty for withdrawing early for a specific ERC20 token mapping (address => uint256) public earlyWithdrawalPenalty; // The boost for a specific timelock category mapping(uint => uint256) public timelockCategoryBoost; // The divisor for a specific token mapping (address => uint256) public divisorERC20; // The allowed dnaVersion for reward boost mapping (uint256 => bool) public allowedDnaVersions; // Map of timelock durartions mapping(uint8 => uint256) public timelockDurations; IHelix public helixERC20; // Helix ERC20 Token IERC721 public konduxERC721Founders; // Kondux ERC721 Founders Token address public konduxERC721kNFT; // Kondux ERC721 kNFT Token ITreasury public treasury; // Treasury Contract // Events // Emitted when a staker withdraws their rewards event Withdraw(address indexed user, uint256 liquidAmount, uint256 fees); // Emitted when a staker withdraws all their rewards event WithdrawAll(address indexed staker, uint256 amount); // Emitted when a staker compounds their rewards event Compound(address indexed staker, uint256 amount); // Emitted when a staker stakes their tokens event Stake(uint indexed id, address indexed staker, address token, uint256 amount); // Emitted when a staker unstakes their tokens event Unstake(address indexed staker, uint256 amount); // Emitted when a staker receives a reward event Reward(address indexed user, uint256 netRewards, uint256 fees); // Emitted when the rewards per hour is updated for a token event NewAPR(uint256 indexed amount, address indexed token); // Emitted when the minimum stake is updated for a token event NewMinStake(uint256 indexed amount, address indexed token); // Emitted when the compound frequency is updated for a token event NewCompoundFreq(uint256 indexed amount, address indexed token); // Emitted when the Helix ERC20 token is updated event NewHelixERC20(address indexed helixERC20); // Emitted when the Kondux ERC721 Founders token is updated event NewKonduxERC721Founders(address indexed konduxERC721Founders); // Emitted when the Kondux ERC721 kNFT token is updated event NewKonduxERC721kNFT(address indexed konduxERC721kNFT); // Emitted when the treasury address is updated event NewTreasury(address indexed treasury); // Emitted when the withdrawal fee is updated for a token event NewWithdrawalFee(uint256 indexed amount, address indexed token); // Emitted when the founders reward boost is updated for a token event NewFoundersRewardBoost(uint256 indexed amount, address indexed token); // Emitted when the kNFT reward boost is updated for a token event NewKNFTRewardBoost(uint256 indexed amount, address indexed token); // Emitted when a token is authorized or deauthorized for staking event NewAuthorizedERC20(address indexed token, bool indexed authorized); // Emitted when the ratio is updated for a token event NewRatio(uint256 indexed amount, address indexed token); // Emitted when a new divisor is set for a token event NewDivisorERC20(uint256 indexed amount, address indexed token); /** * @dev Initializes the staking contract with the provided parameters. * * @param _authority The address of the authority contract. * @param _konduxERC20 The address of the Kondux ERC20 token contract. * @param _treasury The address of the treasury contract. * @param _konduxERC721Founders The address of the Kondux ERC721 Founders token contract. * @param _konduxERC721kNFT The address of the Kondux ERC721 kNFT token contract. * @param _helixERC20 The address of the Helix ERC20 token contract. * * The constructor sets up the initial state of the staking contract by initializing contract variables, * setting up default staking token parameters, and authorizing the Kondux ERC20 token for staking. */ constructor( address _authority, address _konduxERC20, address _treasury, address _konduxERC721Founders, address _konduxERC721kNFT, address _helixERC20 ) AccessControlled(IAuthority(_authority)) { // Ensure the provided addresses are valid require(_konduxERC20 != address(0), "Kondux ERC20 address is not set"); require(_treasury != address(0), "Treasury address is not set"); require(_konduxERC721Founders != address(0), "Kondux ERC721 Founders address is not set"); require(_konduxERC721kNFT != address(0), "Kondux ERC721 kNFT address is not set"); require(_helixERC20 != address(0), "Helix ERC20 address is not set"); // Initialize contract variables konduxERC721Founders = IERC721(_konduxERC721Founders); konduxERC721kNFT = _konduxERC721kNFT; helixERC20 = IHelix(_helixERC20); treasury = ITreasury(_treasury); timelockDurations[0] = 30 days; // 1 month timelockDurations[1] = 90 days; // 3 months timelockDurations[2] = 180 days; // 6 months timelockDurations[3] = 365 days; // 1 year // Set up default staking token parameters setDivisorERC20(10_000, _konduxERC20); // 10,000 basis points setWithdrawalFee(100, _konduxERC20); // 1% fee on withdrawal or 100 / 10_000 setFoundersRewardBoost(1_000, _konduxERC20); // 10% boost (=110%) on rewards or 1,000,000/10,000,000 setkNFTRewardBoost(500, _konduxERC20); // 5% boost on rewards or 500 / setMinStake(10_000_000, _konduxERC20); // 10,000,000 wei setAPR(25, _konduxERC20); // 0.00285%/h or 25% APR setCompoundFreq(60 * 60 * 24, _konduxERC20); // 24 hours setRatio(10_000, _konduxERC20); // 10,000:1 ratio, adjusted for kondux ERC20 decimals setEarlyWithdrawalPenalty(_konduxERC20, 10); // 10% penalty setTimelockCategoryBoost(1, 100); // 1% boost for 90 days timelock setTimelockCategoryBoost(2, 300); // 3% boost for 180 days timelock setTimelockCategoryBoost(3, 900); // 9% boost for 365 days timelock setAllowedDnaVersion(1, true); // allow DNA version 1 setDecimalsERC20(helixERC20.decimals(), _helixERC20); // set decimals for Helix ERC20 token setDecimalsERC20(IKonduxERC20(_konduxERC20).decimals(), _konduxERC20); // set decimals for Kondux ERC20 token _setAuthorizedERC20(_konduxERC20, true); } /** * @dev This function allows a user to deposit a specified amount of an authorized token with a selected timelock period. * The function checks the user's token balance, allowance, and the timelock value before proceeding. * It then creates a new deposit record, sets the timelock based on the selected category, and updates the user's * deposit list and total staked amount. The specified amount of tokens is transferred from the user to the vault, * and an equivalent amount of reward tokens is minted for the user. * @param _amount The amount of tokens to deposit. * @param _timelock The timelock category, represented as an integer (0-4). * @param _token The address of the token contract. * @return _id The deposit ID assigned to this deposit. */ function deposit(uint256 _amount, uint8 _timelock, address _token) public returns (uint) { // Check if the token address is set require(_token != address(0), "Token address is not set"); // Check if the token is authorized for staking require(authorizedERC20[_token], "Token not authorized"); // Check if the deposit amount is greater than or equal to the minimum required stake require(_amount >= minStakeERC20[_token], "Amount smaller than minimimum deposit"); IERC20 konduxERC20 = IERC20(_token); // Check if the user has enough balance to stake the specified amount require(konduxERC20.balanceOf(msg.sender) >= _amount, "Can't stake more than you own"); // Check if the user has approved the staking contract to spend the specified amount require(konduxERC20.allowance(msg.sender, address(this)) >= _amount, "Allowance not set"); // Check if the selected timelock category is valid (between 0 and 3) require(_timelock <= 3, "Invalid timelock"); // Get the current deposit ID uint _id = _depositIds.current(); // Create a new deposit record for the user userDeposits[_id] = Staker({ token: _token, staker: msg.sender, deposited: _amount, unclaimedRewards: 0, timelock: block.timestamp + timelockDurations[_timelock], // Set the timelock period based on the selected category timelockCategory: _timelock, timeOfLastUpdate: block.timestamp, lastDepositTime: block.timestamp, redeemed: 0, ratioERC20: ratioERC20[_token] }); // Add the deposit ID to the user's deposit list userDepositsIds[msg.sender].push(_id); // Update the user's total staked amount _addTotalStakedAmount(_amount, _token, msg.sender); // Mint an equivalent amount of reward tokens for the user // Get the decimals of the original staked token and Helix uint8 originalTokenDecimals = decimalsERC20[_token]; uint8 helixDecimals = decimalsERC20[address(helixERC20)]; // Calculate the decimal difference uint decimalDifference; if (helixDecimals > originalTokenDecimals) { decimalDifference = helixDecimals - originalTokenDecimals; } else { decimalDifference = 0; } // Transfer the deposited tokens from the user to the vault konduxERC20.transferFrom(msg.sender, authority.vault(), _amount); // Mint an equivalent amount of reward tokens for the user, adjusted based on the decimal difference helixERC20.mint(msg.sender, _amount * ratioERC20[_token] * (10 ** decimalDifference)); // Increment the deposit ID counter _depositIds.increment(); // Emit a Stake event emit Stake(_id, msg.sender, _token, _amount); return _id; } /** * @dev This function allows the owner of a deposit to stake their earned rewards. * It verifies that the caller is the deposit owner and that the compounding is not happening too soon. * The function calculates the rewards, resets the unclaimed rewards to zero, and updates the deposit record. * The total staked amount is updated, and an equivalent amount of reward tokens is minted for the user. * @param _depositId The ID of the deposit whose rewards are to be staked. */ function stakeRewards(uint _depositId) public { // Verify that the caller is the owner of the deposit require(msg.sender == userDeposits[_depositId].staker, "You are not the owner of this deposit"); // Verify that the user is not trying to compound rewards too soon // require(compoundRewardsTimer(_depositId) == 0, "Tried to compound rewards too soon"); // Calculate the rewards and add any unclaimed rewards uint256 rewards = calculateRewards(msg.sender, _depositId) + userDeposits[_depositId].unclaimedRewards; // Check if the rewards are non-zero require(rewards > 0, "No rewards available"); // Reset the unclaimed rewards to zero userDeposits[_depositId].unclaimedRewards = 0; // Update the deposited amount with the compounded rewards userDeposits[_depositId].deposited += rewards; // Update the time of the last update userDeposits[_depositId].timeOfLastUpdate = block.timestamp; // Update the user's total staked amount _addTotalStakedAmount(rewards, userDeposits[_depositId].token, userDeposits[_depositId].staker); // Mint an equivalent amount of reward tokens for the user // Get the decimals of the original staked token and Helix uint8 originalTokenDecimals = decimalsERC20[userDeposits[_depositId].token]; uint8 helixDecimals = decimalsERC20[address(helixERC20)]; // Calculate the decimal difference uint decimalDifference; if (helixDecimals > originalTokenDecimals) { decimalDifference = helixDecimals - originalTokenDecimals; } else { decimalDifference = 0; } // Mint the calculated rewards for the user, adjusted based on the decimal difference helixERC20.mint(msg.sender, rewards * userDeposits[_depositId].ratioERC20 * (10 ** decimalDifference)); // Emit a Compound event emit Compound(msg.sender, rewards); } /** * @dev This function allows the owner of a deposit to claim their earned rewards. * It verifies that the caller is the deposit owner and that the timelock has passed. * The function calculates the rewards, resets the unclaimed rewards to zero, and updates the deposit record. * The reward tokens are burned, and the earned rewards are transferred to the user from the vault. * The function emits a Reward event upon successful execution. * @param _depositId The ID of the deposit whose rewards are to be claimed. */ function claimRewards(uint _depositId) public { require(msg.sender == userDeposits[_depositId].staker, "You are not the owner of this deposit"); require(block.timestamp >= userDeposits[_depositId].timelock, "Timelock not passed"); uint256 rewards = calculateRewards(msg.sender, _depositId) + userDeposits[_depositId].unclaimedRewards; require(rewards > 0, "You have no rewards"); userDeposits[_depositId].unclaimedRewards = 0; userDeposits[_depositId].timeOfLastUpdate = block.timestamp; IERC20 konduxERC20 = IERC20(userDeposits[_depositId].token); uint256 netRewards = (rewards * (10_000 - withdrawalFeeERC20[userDeposits[_depositId].token])) / divisorERC20[userDeposits[_depositId].token]; uint256 fees = rewards - netRewards; konduxERC20.transferFrom(authority.vault(), msg.sender, netRewards); _addTotalRewardedAmount(netRewards, userDeposits[_depositId].token, userDeposits[_depositId].staker); _addTotalWithdrawalFees(rewards - netRewards, userDeposits[_depositId].token); emit Reward(msg.sender, netRewards, fees); } /** * @dev This function allows the owner of a deposit to withdraw a specified amount of their deposited tokens. * It verifies that the timelock has passed, the caller is the deposit owner, and the withdrawal amount * is within the available limits. The function calculates the rewards, updates the deposit record, and * transfers the liquid amount to the user after applying the withdrawal fee. The collateral tokens are burned. * The function emits a Withdraw event upon successful execution. * @param _amount The amount of tokens to withdraw. * @param _depositId The ID of the deposit from which to withdraw the tokens. */ function withdraw(uint256 _amount, uint _depositId) public { // Verify that the timelock has passed require(block.timestamp >= userDeposits[_depositId].timelock, "Timelock not passed"); // Verify that the caller is the owner of the deposit require(msg.sender == userDeposits[_depositId].staker, "You are not the owner of this deposit"); // Verify that the withdrawal amount is within the available limits require(userDeposits[_depositId].deposited >= _amount, "Can't withdraw more than you have"); // Verify that the withdrawal amount is less than or equal to the collateral tokens the user has require(_amount * userDeposits[_depositId].ratioERC20 <= helixERC20.balanceOf(msg.sender), "Can't withdraw more tokens than the collateral you have"); // Calculate the rewards uint256 _rewards = calculateRewards(msg.sender, _depositId); // Update the deposit record userDeposits[_depositId].deposited -= _amount; userDeposits[_depositId].timeOfLastUpdate = block.timestamp; userDeposits[_depositId].unclaimedRewards += _rewards; // Calculate the liquid amount to transfer after applying the withdrawal fee uint256 _liquid = (_amount * (divisorERC20[userDeposits[_depositId].token] - withdrawalFeeERC20[userDeposits[_depositId].token])) / divisorERC20[userDeposits[_depositId].token]; uint256 fees = _amount - _liquid; // Get the token contract IERC20 konduxERC20 = IERC20(userDeposits[_depositId].token); // Check if the treasury contract has approved the staking contract to withdraw the tokens require(konduxERC20.allowance(authority.vault(), address(this)) >= _liquid, "Treasury Contract need to approve Staking Contract to withdraw your tokens -- please call an Admin"); // Subtract the staked amount _subtractStakedAmount(_amount, userDeposits[_depositId].token, userDeposits[_depositId].staker); // Get the decimals of the original staked token and Helix uint8 originalTokenDecimals = decimalsERC20[userDeposits[_depositId].token]; uint8 helixDecimals = decimalsERC20[address(helixERC20)]; // Calculate the decimal difference uint decimalDifference; if (originalTokenDecimals < helixDecimals) { decimalDifference = helixDecimals - originalTokenDecimals; } else { decimalDifference = 0; } // Burn the equivalent amount of collateral tokens, adjusted based on the decimal difference helixERC20.burn(msg.sender, _amount * userDeposits[_depositId].ratioERC20 * (10 ** decimalDifference)); // Transfer the liquid amount to the user konduxERC20.transferFrom(authority.vault(), msg.sender, _liquid); // Update the user's total rewarded amount + total rewarded amount for the token _addTotalRewardedAmount(_liquid, userDeposits[_depositId].token, userDeposits[_depositId].staker); _addTotalWithdrawalFees(_amount - _liquid, userDeposits[_depositId].token); // Emit a Withdraw event emit Withdraw(msg.sender, _liquid, fees); } /** * @dev This function allows the owner of a deposit to withdraw a specified amount of their deposited tokens * before the timelock has passed. The user is punished by not receiving any reward boosts and paying an extra * fee proportional to the time left until the lock (the closer to the end of the locking time, the smaller the fee, * starting at 10%). * It verifies that the caller is the deposit owner, and the withdrawal amount is within the available limits. * The function calculates the rewards, updates the deposit record, and transfers the liquid amount to the user * after applying the extra fee and withdrawal fee. The collateral tokens are burned. * The function emits a Withdraw event upon successful execution. * @param _amount The amount of tokens to withdraw. * @param _depositId The ID of the deposit from which to withdraw the tokens. */ function earlyUnstake(uint256 _amount, uint _depositId) public { // Verify that the caller is the owner of the deposit require(msg.sender == userDeposits[_depositId].staker, "You are not the owner of this deposit"); // Verify that the withdrawal amount is within the available limits require(userDeposits[_depositId].deposited >= _amount, "Can't withdraw more than you have"); // Verify that the withdrawal amount is less than or equal to the collateral tokens the user has require(_amount * userDeposits[_depositId].ratioERC20 <= helixERC20.balanceOf(msg.sender), "Can't withdraw more tokens than the collateral you have"); // Verify if the timelock has passed require(block.timestamp < userDeposits[_depositId].timelock, "Timelock has passed"); // Calculate the extra fee proportional to the time left until the lock (the closer to the end of the locking time, the smaller the fee) uint256 timeLeft = userDeposits[_depositId].timelock - block.timestamp; uint256 lockDuration = userDeposits[_depositId].timelock - userDeposits[_depositId].lastDepositTime; uint256 extraFee = (_amount * earlyWithdrawalPenalty[userDeposits[_depositId].token] * timeLeft) / (lockDuration * 100); // If extra fee is more than the amount, set it to the amount if (extraFee > _amount) { extraFee = _amount; } // If extra fee is zero, apply 1% fee if (extraFee == 0) { extraFee = (_amount * 1) / 100; } // Calculate the total fee percentage uint256 totalFeePercentage = extraFee + withdrawalFeeERC20[userDeposits[_depositId].token]; // Calculate the liquid amount to transfer after applying the total fee uint256 _liquid = (_amount - totalFeePercentage); uint256 fees = _amount - _liquid; // Update the deposit record userDeposits[_depositId].deposited -= _amount; userDeposits[_depositId].timeOfLastUpdate = block.timestamp; // Get the token contract IERC20 konduxERC20 = IERC20(userDeposits[_depositId].token); // Check if the treasury contract has approved the staking contract to withdraw the tokens require(konduxERC20.allowance(authority.vault(), address(this)) >= _liquid, "Treasury Contract need to approve Staking Contract to withdraw your tokens -- please call an Admin"); // Subtract the staked amount _subtractStakedAmount(_amount, userDeposits[_depositId].token, userDeposits[_depositId].staker); // Calculate the decimal difference uint decimalDifference; if (decimalsERC20[userDeposits[_depositId].token] < decimalsERC20[address(helixERC20)]) { decimalDifference = decimalsERC20[address(helixERC20)] - decimalsERC20[userDeposits[_depositId].token]; } else { decimalDifference = 0; } // Burn the equivalent amount of collateral tokens, adjusted based on the decimal difference helixERC20.burn(msg.sender, _amount * userDeposits[_depositId].ratioERC20 * (10 ** decimalDifference)); // Transfer the liquid amount to the user konduxERC20.transferFrom(authority.vault(), msg.sender, _liquid); // Update the user's total rewarded amount + total rewarded amount for the token _addTotalRewardedAmount(_liquid, userDeposits[_depositId].token, userDeposits[_depositId].staker); _addTotalWithdrawalFees(_amount - _liquid, userDeposits[_depositId].token); // Emit a Withdraw event emit Withdraw(msg.sender, _liquid, fees); } /** * @dev This function allows the owner of a deposit to withdraw a specified amount of their deposited tokens * and claim their earned rewards in a single transaction. It calls the withdraw and claimRewards functions. * @param _amount The amount of tokens to withdraw. * @param _depositId The ID of the deposit from which to withdraw the tokens and claim the rewards. */ function withdrawAndClaim(uint256 _amount, uint _depositId) public { withdraw(_amount, _depositId); claimRewards(_depositId); } /** * @dev This function returns the remaining time until the next allowed compounding action for a given deposit ID. * It calculates the remaining time based on the compound frequency for the deposited token. * If the timer has already passed, it returns 0. * @param _depositId The ID of the deposit for which to return the compound timer. * @return remainingTime The remaining time until the next allowed compounding action in seconds. */ function compoundRewardsTimer(uint _depositId) public view returns (uint256 remainingTime) { uint256 lastUpdateTime = userDeposits[_depositId].timeOfLastUpdate; uint256 compoundFrequency = compoundFreqERC20[userDeposits[_depositId].token]; if (block.timestamp >= lastUpdateTime + compoundFrequency) { return 0; } remainingTime = (lastUpdateTime + compoundFrequency) - block.timestamp; return remainingTime; } /** * @dev This function calculates the rewards for a specified staker and deposit ID. The rewards calculation * considers the deposit's elapsed time, staked amount, and a 25% APY compounded hourly. * If the provided staker is not the owner of the deposit, the function returns 0. * @param _staker The address of the staker for which to calculate the rewards. * @param _depositId The ID of the deposit for which to calculate the rewards. * @return rewards The calculated rewards for the specified staker and deposit ID. */ function calculateRewards(address _staker, uint _depositId) public view returns (uint256 rewards) { // Retrieve deposit details by _depositId Staker memory deposit_ = userDeposits[_depositId]; // Check if the staker is the owner of the deposit; if not, return 0 if (deposit_.staker != _staker) { return 0; } // Calculate the elapsed time since the last update uint256 elapsedTime = block.timestamp - deposit_.timeOfLastUpdate; // Get the deposited amount uint256 depositedAmount = deposit_.deposited; // Calculate the base reward per second using the token's APR uint256 tokenApr = aprERC20[deposit_.token]; /** * @dev This line calculates the reward earned per second by a staker for their deposit, considering the deposit's APR (annual percentage rate). * * The formula breakdown: * 1. depositedAmount: The amount of tokens the staker deposited. * 2. tokenApr: The annual percentage rate for the token in question (e.g. 25% APR). * 3. 1e18: A scaling factor used to maintain precision in the calculations (10^18 or 1 followed by 18 zeros). * 4. 365 * 24 * 3600: The total number of seconds in a year, used to convert the APR to a per-second rate. * 5. 100: Used to convert the APR percentage to a decimal (e.g. 25% becomes 0.25). * * The formula calculates the per-second reward by multiplying the deposited amount and the token's APR, and then scaling it up by 1e18. * After that, it divides the result by the total number of seconds in a year and by 100 to adjust for the percentage. * * Using 1e18 maintains precision in the calculation, avoiding truncation errors due to integer division in Solidity. * By scaling up the result and performing the divisions afterward, the calculation maintains precision without truncating intermediate results to zero. */ uint256 rewardPerSecond = (depositedAmount * tokenApr * 1e18) / (365 * 24 * 3600 * 100); // Calculate the base reward based on elapsed time uint256 _reward = elapsedTime * rewardPerSecond / 1e18; // Calculate the boost percentage uint256 boostPercentage = calculateBoostPercentage(_staker, _depositId); // Calculate the final reward by applying the boost percentage _reward = (_reward * boostPercentage) / divisorERC20[deposit_.token]; // Return the calculated reward return _reward; } // Internal functions: /** * @dev This internal function calculates the compounded rewards for a given deposited amount and number of elapsed periods. * The function assumes a fixed 25% APR and 8760 periods per year (hourly compounding). It uses exponentiation to calculate * the compounded rewards using the formula A = P * (1 + r/n)^(nt), where: * A: final amount after compounding * P: initial deposited amount * r: annual interest rate (25%) * n: number of periods in a year (8760) * t: number of elapsed periods * @param _depositedAmount The initial deposited amount. * @param _periodsElapsed The number of elapsed periods (hours) since the deposit. * @return compound The calculated compounded rewards for the given deposited amount and elapsed periods. */ function _calculateCompound(uint256 _depositedAmount, uint256 _periodsElapsed) internal pure returns (uint256 compound) { uint256 periodsInYear = 8760; // 24 hours * 365 days uint256 compoundFactor = 1 + (25 * 1e1 / periodsInYear); //Calculate compounded rewards using exponentiation (A = P * (1 + r/n)^(nt)) compound = _depositedAmount * (compoundFactor ** _periodsElapsed) / (1e1 ** _periodsElapsed); return compound; } // Functions for modifying staking mechanism variables: /** * @dev This internal function is used to update the total rewarded amount and the total rewarded amount * for a specific user and token. It is called when rewards are distributed or staked. * @param _amount The amount of tokens to add to the total rewarded and user's total rewarded. * @param _token The address of the token contract. * @param _user The address of the user receiving the rewards. */ function _addTotalRewardedAmount(uint256 _amount, address _token, address _user) internal { totalRewarded[_token] += _amount; userTotalRewardedByCoin[_token][_user] += _amount; } /** * @dev This internal function adds the given amount to the total staked amount for a specified token * and increases the staked amount for the user by the same amount. * @param _amount The amount to add to the total staked amount and user's staked amount. * @param _token The address of the token for which to update the staked amount. * @param _user The address of the user whose staked amount should be increased. */ function _addTotalStakedAmount(uint256 _amount, address _token, address _user) internal { totalStaked[_token] += _amount; userTotalStakedByCoin[_token][_user] += _amount; } /** * @dev This internal function subtracts the given amount from the total staked amount for a specified token * and decreases the staked amount for the user by the same amount. * @param _amount The amount to subtract from the total staked amount and user's staked amount. * @param _token The address of the token for which to update the staked amount. * @param _user The address of the user whose staked amount should be decreased. */ function _subtractStakedAmount(uint256 _amount, address _token, address _user) internal { // do a underflow check require(totalStaked[_token] >= _amount, "Staking: Not enough staked (Contract)"); require(userTotalStakedByCoin[_token][_user] >= _amount, "Staking: Not enough staked (User)"); totalStaked[_token] -= _amount; userTotalStakedByCoin[_token][_user] -= _amount; } /** * @dev This internal function adds the given amount to the total withdrawal fees for a specified token. * @param _amount The amount to add to the total withdrawal fees. * @param _token The address of the token for which to update the withdrawal fees. */ function _addTotalWithdrawalFees(uint256 _amount, address _token) internal { totalWithdrawalFees[_token] += _amount; } /** * @dev This function sets the APR for a specified token. * @param _apr The rewards per hour value to be set, as x% APR. (e.g. 25 = 25%) * @param _tokenId The address of the token for which to set the rewards per hour. */ function setAPR(uint256 _apr, address _tokenId) public onlyGovernor { // Check if the token address is set require(_tokenId != address(0), "Token address is not set"); aprERC20[_tokenId] = _apr; emit NewAPR(_apr, _tokenId); } /** * @dev This function sets the minimum staking amount for a specified token. * @param _minStake The minimum staking amount to be set, in wei. * @param _tokenId The address of the token for which to set the minimum staking amount. */ function setMinStake(uint256 _minStake, address _tokenId) public onlyGovernor { // Check if the token address is set require(_tokenId != address(0), "Token address is not set"); minStakeERC20[_tokenId] = _minStake; emit NewMinStake(_minStake, _tokenId); } /** * @dev This function sets the ratio for a specified ERC20 token. * @param _ratio The ratio value to be set. * @param _tokenId The address of the token for which to set the ratio. */ function setRatio(uint256 _ratio, address _tokenId) public onlyGovernor { // Check if the token address is set require(_tokenId != address(0), "Token address is not set"); ratioERC20[_tokenId] = _ratio; emit NewRatio(_ratio, _tokenId); } /** * @dev This function sets the address of the Helix ERC20 contract. * @param _helix The address of the Helix ERC20 contract. */ function setHelixERC20(address _helix) public onlyGovernor { require(_helix != address(0), "Helix address cannot be 0x0"); helixERC20 = IHelix(_helix); emit NewHelixERC20(_helix); } /** * @dev This function sets the address of the konduxERC721Founders contract. * @param _konduxERC721Founders The address of the konduxERC721Founders contract. */ function setKonduxERC721Founders(address _konduxERC721Founders) public onlyGovernor { require(_konduxERC721Founders != address(0), "Founders address cannot be 0x0"); konduxERC721Founders = IERC721(_konduxERC721Founders); emit NewKonduxERC721Founders(_konduxERC721Founders); } /** * @dev This function sets the address of the konduxERC721kNFT contract. * @param _konduxERC721kNFT The address of the konduxERC721kNFT contract. */ function setKonduxERC721kNFT(address _konduxERC721kNFT) public onlyGovernor { require(_konduxERC721kNFT != address(0), "kNFT address cannot be 0x0"); konduxERC721kNFT = _konduxERC721kNFT; emit NewKonduxERC721kNFT(_konduxERC721kNFT); } /** * @dev This function sets the address of the Treasury contract. * @param _treasury The address of the Treasury contract. */ function setTreasury(address _treasury) public onlyGovernor { require(_treasury != address(0), "Treasury address cannot be 0x0"); treasury = ITreasury(_treasury); emit NewTreasury(_treasury); } /** * @dev This function sets the withdrawal fee for a specified token. * @param _withdrawalFee The withdrawal fee value to be set. * @param _tokenId The address of the token for which to set the withdrawal fee. */ function setWithdrawalFee(uint256 _withdrawalFee, address _tokenId) public onlyGovernor { // Check if the token address is set require(_tokenId != address(0), "Token address is not set"); require(_withdrawalFee <= divisorERC20[_tokenId], "Withdrawal fee cannot be more than 100%"); withdrawalFeeERC20[_tokenId] = _withdrawalFee; emit NewWithdrawalFee(_withdrawalFee, _tokenId); } /** * @dev This function sets the founders reward boost for a specified token. * @param _foundersRewardBoost The founders reward boost value to be set. * @param _tokenId The address of the token for which to set the founders reward boost. */ function setFoundersRewardBoost(uint256 _foundersRewardBoost, address _tokenId) public onlyGovernor { // Check if the token address is set require(_tokenId != address(0), "Token address is not set"); foundersRewardBoostERC20[_tokenId] = _foundersRewardBoost; emit NewFoundersRewardBoost(_foundersRewardBoost, _tokenId); } /** * @dev This function sets the kNFT reward boost for a specified token. * @param _kNFTRewardBoost The kNFT reward boost value to be set. * @param _tokenId The address of the token for which to set the kNFT reward boost. */ function setkNFTRewardBoost(uint256 _kNFTRewardBoost, address _tokenId) public onlyGovernor { // Check if the token address is set require(_tokenId != address(0), "Token address is not set"); kNFTRewardBoostERC20[_tokenId] = _kNFTRewardBoost; emit NewKNFTRewardBoost(_kNFTRewardBoost, _tokenId); } /** * @dev This function sets the compound frequency for a specified token. * @param _compoundFreq The compound frequency value to be set. * @param _tokenId The address of the token for which to set the compound frequency. */ function setCompoundFreq(uint256 _compoundFreq, address _tokenId) public onlyGovernor { // Check if the token address is set require(_tokenId != address(0), "Token address is not set"); compoundFreqERC20[_tokenId] = _compoundFreq; emit NewCompoundFreq(_compoundFreq, _tokenId); } /** * @dev This function sets the penalty percentage for early withdrawal of a specified token. * @param _token The address of the token for which to set the penalty percentage. * @param penaltyPercentage The penalty percentage value to be set. Must be between 0 and 100. */ function setEarlyWithdrawalPenalty(address _token, uint256 penaltyPercentage) public onlyGovernor { // Check if the token address is set require(_token != address(0), "Token address is not set"); require(penaltyPercentage <= 100, "Penalty percentage must be between 0 and 100"); earlyWithdrawalPenalty[_token] = penaltyPercentage; } /** * @dev This function sets the timelock category boost for a specified category. * @param _category The category for which to set the boost. * @param _boost The boost value to be set. */ function setTimelockCategoryBoost(uint _category, uint256 _boost) public onlyGovernor { timelockCategoryBoost[_category] = _boost; } /** * @dev This function sets the divisor for a specified token. * @param _divisor The divisor value to be set. * @param _tokenId The address of the token for which to set the divisor. */ function setDivisorERC20(uint256 _divisor, address _tokenId) public onlyGovernor { // Check if the token address is set require(_tokenId != address(0), "Token address is not set"); divisorERC20[_tokenId] = _divisor; emit NewDivisorERC20(_divisor, _tokenId); } /** * @dev This internal function sets whether an ERC20 token is authorized as a staking currency. * Emits a {NewAuthorizedERC20} event. * @param _token The address of the token to be authorized or deauthorized. * @param _authorized True to authorize the token, false to deauthorize. */ function _setAuthorizedERC20(address _token, bool _authorized) internal { require(_token != address(0), "Token address cannot be 0x0"); if (_authorized == true) { require(aprERC20[_token] > 0, "Rewards per hour must be greater than 0"); require(compoundFreqERC20[_token] > 0, "Compound frequency must be greater than 0"); require(withdrawalFeeERC20[_token] > 0, "Withdrawal fee must be greater than 0"); require(foundersRewardBoostERC20[_token] > 0, "Founders reward boost must be greater than 0"); require(kNFTRewardBoostERC20[_token] > 0, "kNFT reward boost must be greater than 0"); require(ratioERC20[_token] > 0, "Ratio must be greater than 0"); require(minStakeERC20[_token] > 0, "Minimum stake must be greater than 0"); require(divisorERC20[_token] > 0, "Divisor must be greater than 0"); require(IERC20(_token).totalSupply() > 0, "Token total supply must be greater than 0"); } authorizedERC20[_token] = _authorized; emit NewAuthorizedERC20(_token, _authorized); } /** * @dev This function sets whether an ERC20 token is authorized as a staking currency. * Emits a {NewAuthorizedERC20} event. * @param _token The address of the token to be authorized or deauthorized. * @param _authorized True to authorize the token, false to deauthorize. */ function setAuthorizedERC20(address _token, bool _authorized) public onlyGovernor { // Check if the token address is set require(_token != address(0), "Token address is not set"); _setAuthorizedERC20(_token, _authorized); } /** * @dev This function sets the version of dna that is allowed to be used for reward bonus * @param _dnaVersion The dna version to be set. * @param _allowed True to allow the dna version, false to disallow. */ function setAllowedDnaVersion(uint256 _dnaVersion, bool _allowed) public onlyGovernor { allowedDnaVersions[_dnaVersion] = _allowed; } /** * @dev This function sets the decimals of a specified token. * @param _decimals The decimals value to be set. * @param _tokenId The address of the token for which to set the decimals. */ function setDecimalsERC20(uint8 _decimals, address _tokenId) public onlyGovernor { // Check if the token address is set require(_tokenId != address(0), "Token address is not set"); decimalsERC20[_tokenId] = _decimals; } /** * @dev This function adds a new staking token with its parameters. * Emits various events based on the setter functions called during token addition. * Emits a {NewAuthorizedERC20} event at the end. * @param _token The address of the new staking token. * @param _apr The rewards per hour for the new staking token. * @param _compoundFreq The compound frequency for the new staking token. * @param _withdrawalFee The withdrawal fee for the new staking token. * @param _foundersRewardBoost The founders reward boost for the new staking token. * @param _kNFTRewardBoost The kNFT reward boost for the new staking token. * @param _ratio The ratio for the new staking token. * @param _minStake The minimum stake for the new staking token. */ function addNewStakingToken(address _token, uint256 _apr, uint256 _compoundFreq, uint256 _withdrawalFee, uint256 _foundersRewardBoost, uint256 _kNFTRewardBoost, uint256 _ratio, uint256 _minStake) public onlyGovernor { require(_token != address(0), "Token address cannot be 0x0"); require(_apr > 0, "Rewards per hour must be greater than 0"); require(_compoundFreq > 0, "Compound frequency must be greater than 0"); require(_withdrawalFee > 0, "Withdrawal fee must be greater than 0"); require(_foundersRewardBoost > 0, "Founders reward boost must be greater than 0"); require(_kNFTRewardBoost > 0, "kNFT reward boost must be greater than 0"); require(_ratio > 0, "Ratio must be greater than 0"); require(_minStake > 0, "Minimum stake must be greater than 0"); require(IERC20(_token).totalSupply() > 0, "Token total supply must be greater than 0"); setDivisorERC20(10_000, _token); setFoundersRewardBoost(_foundersRewardBoost, _token); setkNFTRewardBoost(_kNFTRewardBoost, _token); setAPR(_apr, _token); setRatio(_ratio, _token); setWithdrawalFee(_withdrawalFee, _token); setCompoundFreq(_compoundFreq, _token); setMinStake(_minStake, _token); setDecimalsERC20(IERC20Metadata(_token).decimals(), _token); _setAuthorizedERC20(_token, true); } // Functions for getting staking mechanism variables: /** * @dev This function returns the time of the last update for the specified deposit ID. * @param _depositId The ID of the deposit for which the time of the last update is requested. * @return _timeOfLastUpdate The time of the last update for the specified deposit ID. */ function getTimeOfLastUpdate(uint _depositId) public view returns (uint256 _timeOfLastUpdate) { return userDeposits[_depositId].timeOfLastUpdate; } /** * @dev This function returns the staked amount for the specified deposit ID. * @param _depositId The ID of the deposit for which the staked amount is requested. * @return _deposited The staked amount for the specified deposit ID. */ function getStakedAmount(uint _depositId) public view returns (uint256 _deposited) { return userDeposits[_depositId].deposited; } /** * @dev This function returns the APR for the specified token. * @param _tokenId The address of the token for which the rewards per hour are requested. * @return _rewardsPerHour The rewards per hour for the specified token. */ function getAPR(address _tokenId) public view returns (uint256 _rewardsPerHour) { return aprERC20[_tokenId]; } /** * @dev This function returns the Founder's reward boost for the specified token. * @param _tokenId The address of the token for which the Founder's reward boost is requested. * @return _foundersRewardBoost The Founder's reward boost for the specified token. */ function getFoundersRewardBoost(address _tokenId) public view returns (uint256 _foundersRewardBoost) { return foundersRewardBoostERC20[_tokenId]; } /** * @dev This function returns the kNFT reward boost for the specified token. * @param _tokenId The address of the token for which the kNFT reward boost is requested. * @return _kNFTRewardBoost The kNFT reward boost for the specified token. */ function getkNFTRewardBoost(address _tokenId) public view returns (uint256 _kNFTRewardBoost) { return kNFTRewardBoostERC20[_tokenId]; } /** * @dev This function returns the minimum stake for the specified token. * @param _tokenId The address of the token for which the minimum stake is requested. * @return _minStake The minimum stake for the specified token. */ function getMinStake(address _tokenId) public view returns (uint256 _minStake) { return minStakeERC20[_tokenId]; } /** * @dev This function returns the timelock category for the specified deposit ID. * @param _depositId The ID of the deposit for which the timelock category is requested. * @return _timelockCategory The timelock category for the specified deposit ID. */ function getTimelockCategory(uint _depositId) public view returns (uint8 _timelockCategory) { return userDeposits[_depositId].timelockCategory; } /** * @dev This function returns the timelock for the specified deposit ID. * @param _depositId The ID of the deposit for which the timelock is requested. * @return _timelock The timelock for the specified deposit ID. */ function getTimelock(uint _depositId) public view returns (uint256 _timelock) { return userDeposits[_depositId].timelock; } /** * @dev This function returns the deposit IDs for the specified user. * @param _user The address of the user for which the deposit IDs are requested. * @return An array of deposit IDs for the specified user. */ function getDepositIds(address _user) public view returns (uint256[] memory) { return userDepositsIds[_user]; } /** * @dev This function returns the withdrawal fee for the specified token. * @param _tokenId The address of the token for which the withdrawal fee is requested. * @return _withdrawalFee The withdrawal fee for the specified token. */ function getWithdrawalFee(address _tokenId) public view returns (uint256 _withdrawalFee) { return withdrawalFeeERC20[_tokenId]; } /** * @dev This function returns the total amount staked for a specific token. * @param _token The address of the token contract. * @return _totalStaked The total amount staked for the given token. */ function getTotalStaked(address _token) public view returns (uint256 _totalStaked) { return totalStaked[_token]; } /** * @dev This function returns the total amount staked by a specific user for a specific token. * @param _user The address of the user. * @param _token The address of the token contract. * @return _totalStaked The total amount staked by the user for the given token. */ function getUserTotalStakedByCoin(address _user, address _token) public view returns (uint256 _totalStaked) { return userTotalStakedByCoin[_token][_user]; } /** * @dev This function returns the total rewards earned for a specific token. * @param _token The address of the token contract. * @return _totalRewards The total rewards earned for the given token. */ function getTotalRewards(address _token) public view returns (uint256 _totalRewards) { return totalRewarded[_token]; } /** * @dev This function returns the total rewards earned by a specific user for a specific token. * @param _user The address of the user. * @param _token The address of the token contract. * @return _totalRewards The total rewards earned by the user for the given token. */ function getUserTotalRewardsByCoin(address _user, address _token) public view returns (uint256 _totalRewards) { return userTotalRewardedByCoin[_token][_user]; } /** * @dev This function returns the total withdrawal fees for a specific token. * @param _token The address of the token contract. * @return _totalWithdrawalFees The total withdrawal fees for the given token. */ function getTotalWithdrawalFees(address _token) public view returns (uint256 _totalWithdrawalFees) { return totalWithdrawalFees[_token]; } /** * @dev This function returns the timestamp of the deposit with the specified ID. * @param _depositId The id of the deposit for which the timestamp is requested. * @return _depositTimestamp The timestamp of the deposit */ function getDepositTimestamp(uint _depositId) public view returns (uint256 _depositTimestamp) { return userDeposits[_depositId].lastDepositTime; } /** * @dev This function returns the penalty for early withdrawal for the specified token in basis points. (X% = X * 100) * @param token The address of the token for which the penalty is requested. * @return The penalty for early withdrawal for the specified token in basis points. */ function getEarlyWithdrawalPenalty(address token) public view returns (uint256) { return earlyWithdrawalPenalty[token]; } /** * @dev This function returns the timelock category boost for the specified category. * @param _category The category for which the timelock category boost is requested. * @return The timelock category boost for the specified category. */ function getTimelockCategoryBoost(uint _category) public view returns (uint256) { return timelockCategoryBoost[_category]; } /** * @dev This function returns the divisor for the specified token. * @param _token The address of the token for which the divisor is requested. * @return The divisor for the specified token. */ function getDivisorERC20(address _token) public view returns (uint256) { return divisorERC20[_token]; } /** * @dev This function returns the permission of usage of a dna version as boost. * @param _dnaVersion The dna version for which the permission is requested. * @return The permission of usage of a dna version as boost */ function getAllowedDnaVersion(uint256 _dnaVersion) public view returns (bool) { return allowedDnaVersions[_dnaVersion]; } /** * @dev This function retrieves the deposit information for a given deposit ID. It returns the staked amount * and the earned rewards (including unclaimed rewards) for the specified deposit. * @param _depositId The ID of the deposit for which to retrieve the information. * @return _stake The staked amount for the specified deposit. * @return _unclaimedRewards The earned rewards (including unclaimed rewards) for the specified deposit. */ function getDepositInfo(uint _depositId) public view returns (uint256 _stake, uint256 _unclaimedRewards) { _stake = userDeposits[_depositId].deposited; _unclaimedRewards = calculateRewards(msg.sender, _depositId) + userDeposits[_depositId].unclaimedRewards; return (_stake, _unclaimedRewards); } /** * @dev This function returns the decimals for the specified token. * @param _token The address of the token for which the decimals are requested. * @return The decimals for the specified token. */ function getDecimalsERC20(address _token) public view returns (uint8) { return decimalsERC20[_token]; } /** * @dev This function returns the ratio for the specified token. * @param _token The address of the token for which the ratio is requested. * @return The ratio for the specified token. */ function getRatioERC20(address _token) public view returns (uint256) { return ratioERC20[_token]; } /** * @dev This function returns the ratio for the specified deposit. * @param _depositId The ID of the deposit for which to retrieve the information. * @return The ratio for the specified deposit. */ function getDepositRatioERC20(uint256 _depositId) public view returns (uint256) { return userDeposits[_depositId].ratioERC20; } /** * @dev This function returns the top 5 bonuses and their corresponding kNFT IDs. * @param _staker The address of the staker. * @param _stakeId The ID of the deposit for which to calculate the boost percentage. * @return top5Bonuses An array of the top 5 bonuses. * @return top5Ids An array of the corresponding kNFT IDs. */ function getTop5BonusesAndIds(address _staker, uint256 _stakeId) public view returns (uint256[] memory top5Bonuses, uint256[] memory top5Ids) { uint256 kNFTBalance = IERC721(konduxERC721kNFT).balanceOf(_staker); // Initialize arrays to store the top 5 bonuses and their corresponding kNFT IDs top5Bonuses = new uint256[](5); top5Ids = new uint256[](5); // Iterate through the staker's kNFTs for (uint256 i = 0; i < kNFTBalance; i++) { uint256 tokenId = IERC721Enumerable(konduxERC721kNFT).tokenOfOwnerByIndex(_staker, i); // if the user's kNFT was received after the deposit date, continue if (IKondux(konduxERC721kNFT).getTransferDate(tokenId) > userDeposits[_stakeId].lastDepositTime) { continue; } // Get the kNFT's DNA version and check if it's allowed int256 dnaVersion = IKondux(konduxERC721kNFT).readGen(tokenId, 0, 1); if (!allowedDnaVersions[uint256(dnaVersion)]) { continue; } // Get the kNFT's boost value and multiply it by 100 to get a percentage int256 dnaBoost = IKondux(konduxERC721kNFT).readGen(tokenId, 1, 2) * 100; // Clamp the boost value to 0 if it's negative if (dnaBoost < 0) { dnaBoost = 0; } // Update the top 5 bonuses array with the current kNFT boost for (uint256 j = 0; j < 5; j++) { if (uint256(dnaBoost) > top5Bonuses[j]) { uint256 temp = top5Bonuses[j]; top5Bonuses[j] = uint256(dnaBoost); dnaBoost = int256(temp); uint256 tempId = top5Ids[j]; top5Ids[j] = tokenId; tokenId = tempId; } } } return (top5Bonuses, top5Ids); } /** * @dev This function returns the top 5 bonuses and their corresponding kNFT IDs. * @param _staker The address of the staker. * @return top5Bonuses An array of the top 5 bonuses. * @return top5Ids An array of the corresponding kNFT IDs. */ function getMaxTop5BonusesAndIds(address _staker) public view returns (uint256[] memory top5Bonuses, uint256[] memory top5Ids) { uint256 kNFTBalance = IERC721(konduxERC721kNFT).balanceOf(_staker); // Initialize arrays to store the top 5 bonuses and their corresponding kNFT IDs top5Bonuses = new uint256[](5); top5Ids = new uint256[](5); // Iterate through the staker's kNFTs for (uint256 i = 0; i < kNFTBalance; i++) { uint256 tokenId = IERC721Enumerable(konduxERC721kNFT).tokenOfOwnerByIndex(_staker, i); // Get the kNFT's DNA version and check if it's allowed int256 dnaVersion = IKondux(konduxERC721kNFT).readGen(tokenId, 0, 1); if (!allowedDnaVersions[uint256(dnaVersion)]) { continue; } // Get the kNFT's boost value and multiply it by 100 to get a percentage int256 dnaBoost = IKondux(konduxERC721kNFT).readGen(tokenId, 1, 2) * 100; // Clamp the boost value to 0 if it's negative if (dnaBoost < 0) { dnaBoost = 0; } // Update the top 5 bonuses array with the current kNFT boost for (uint256 j = 0; j < 5; j++) { if (uint256(dnaBoost) > top5Bonuses[j]) { uint256 temp = top5Bonuses[j]; top5Bonuses[j] = uint256(dnaBoost); dnaBoost = int256(temp); uint256 tempId = top5Ids[j]; top5Ids[j] = tokenId; tokenId = tempId; } } } return (top5Bonuses, top5Ids); } /** * @dev This function calculates the boost percentage for a staker's deposit. * @param _staker The address of the staker. * @param _stakeId The ID of the deposit for which to calculate the boost percentage. * @return boostPercentage The boost percentage for the staker's deposit. */ function calculateKNFTBoostPercentage(address _staker, uint256 _stakeId) public view returns (uint256 boostPercentage) { // Get the top 5 bonuses and their corresponding kNFT IDs (uint256[] memory top5Bonuses, ) = getTop5BonusesAndIds(_staker, _stakeId); // Add the top 5 bonuses to the boost percentage for (uint256 i = 0; i < 5; i++) { boostPercentage += top5Bonuses[i]; } return boostPercentage; } /** * @dev This function calculates the boost percentage for a staker. * @param _staker The address of the staker. * @return boostPercentage The boost percentage for the staker's deposit. */ function calculateMaxKNFTBoostPercentage(address _staker) public view returns (uint256 boostPercentage) { // Get the top 5 bonuses and their corresponding kNFT IDs (uint256[] memory top5Bonuses, ) = getMaxTop5BonusesAndIds(_staker); // Add the top 5 bonuses to the boost percentage for (uint256 i = 0; i < 5; i++) { boostPercentage += top5Bonuses[i]; } return boostPercentage; } /** * @dev This function calculates the boost percentage for a specified staker and deposit ID. * @param _staker The address of the staker for which to calculate the boost. * @param _stakeId The ID of the stake for which to calculate the boost. * @return boostPercentage The calculated boost percentage for the specified staker and deposit ID. */ function calculateBoostPercentage(address _staker, uint _stakeId) public view returns (uint256 boostPercentage) { // Retrieve deposit details by _depositId Staker memory deposit_ = userDeposits[_stakeId]; // Initialize the boost percentage with the base boost percentage for the token boostPercentage = divisorERC20[deposit_.token]; // Check if the staker has Founder's NFTs and add the boost percentage if (IERC721(konduxERC721Founders).balanceOf(_staker) > 0) { boostPercentage += foundersRewardBoostERC20[deposit_.token]; } // Check if the staker has any kNFTs and calculate the top 5 boosts if (IERC721(konduxERC721kNFT).balanceOf(_staker) > 0) { boostPercentage += calculateKNFTBoostPercentage(_staker, _stakeId); } // If the deposit has a timelock category, add the corresponding boost if (deposit_.timelockCategory > 0) { boostPercentage += timelockCategoryBoost[deposit_.timelockCategory]; } return boostPercentage; } /** * @dev A function that agreggates the returned values of getTimelock, getDepositTimestamp, getTimelockCategory, getDepositInfo and calculateKNFTBoostPercentage * @param _staker The address of the staker for which to calculate the boost. * @param _stakeId The ID of the stake for which to calculate the boost. * @return _timelock The timelock for the specified deposit ID. * @return _depositTimestamp The timestamp of the deposit * @return _timelockCategory The timelock category for the specified deposit ID. * @return _stake The staked amount for the specified deposit. * @return _unclaimedRewards The earned rewards (including unclaimed rewards) for the specified deposit. * @return _boostPercentage The calculated boost percentage for the specified staker and deposit ID. */ function getDepositDetails(address _staker, uint _stakeId) public view returns (uint256 _timelock, uint256 _depositTimestamp, uint8 _timelockCategory, uint256 _stake, uint256 _unclaimedRewards, uint256 _boostPercentage) { _timelock = getTimelock(_stakeId); _depositTimestamp = getDepositTimestamp(_stakeId); _timelockCategory = getTimelockCategory(_stakeId); (_stake, _unclaimedRewards) = getDepositInfo(_stakeId); _boostPercentage = calculateBoostPercentage(_staker, _stakeId); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ 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 v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` 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 amount) 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 `amount` 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 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` 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 amount ) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol) pragma solidity ^0.8.0; import "../IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Enumerable is IERC721 { /** * @dev Returns the total amount of tokens stored by the contract. */ function totalSupply() external view returns (uint256); /** * @dev Returns a token ID owned by `owner` at a given `index` of its token list. * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. */ function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256); /** * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. * Use along with {totalSupply} to enumerate all tokens. */ function tokenByIndex(uint256 index) external view returns (uint256); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Counters.sol) pragma solidity ^0.8.0; /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids. * * Include with `using Counters for Counters.Counter;` */ library Counters { struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { unchecked { counter._value += 1; } } function decrement(Counter storage counter) internal { uint256 value = counter._value; require(value > 0, "Counter: decrement overflow"); unchecked { counter._value = value - 1; } } function reset(Counter storage counter) internal { counter._value = 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * 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[EIP 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); }
// SPDX-License-Identifier: AGPL-3.0 pragma solidity >=0.8.9; interface IAuthority { /* ========== EVENTS ========== */ event GovernorPushed(address indexed from, address indexed to, bool _effectiveImmediately); event GuardianPushed(address indexed from, address indexed to, bool _effectiveImmediately); event PolicyPushed(address indexed from, address indexed to, bool _effectiveImmediately); event VaultPushed(address indexed from, address indexed to, bool _effectiveImmediately); event RolePushed(address indexed account, bytes32 _role); event GovernorPulled(address indexed from, address indexed to); event GuardianPulled(address indexed from, address indexed to); event PolicyPulled(address indexed from, address indexed to); event VaultPulled(address indexed from, address indexed to); /* ========== VIEW ========== */ function governor() external view returns (address); function guardian() external view returns (address); function policy() external view returns (address); function vault() external view returns (address); function roles(address _addr) external view returns (bytes32); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; interface IHelix is IERC20, IERC20Metadata { function increaseAllowance(address spender, uint256 addedValue) external returns (bool); function decreaseAllowance(address spender, uint256 subtractedValue) external returns (bool); function burn(address _to, uint256 _amount) external; function mint(address _to, uint256 _amount) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.9; import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol"; interface IKondux { function changeDenominator(uint96 _denominator) external returns (uint96); function setDefaultRoyalty(address receiver, uint96 feeNumerator) external; function setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) external; function setBaseURI(string memory _newURI) external returns (string memory); function tokenURI(uint256 tokenId) external view returns (string memory); function pause() external; function unpause() external; function safeMint(address to, uint256 dna) external returns (uint256); function setDna(uint256 _tokenID, uint256 _dna) external; function getDna(uint256 _tokenID) external view returns (uint256); function readGen(uint256 _tokenID, uint8 startIndex, uint8 endIndex) external view returns (int256); function writeGen(uint256 _tokenID, uint256 inputValue, uint8 startIndex, uint8 endIndex) external; function getTransferDate(uint256 _tokenID) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; interface IKonduxERC20 is IERC20 { function excludedFromFees(address) external view returns (bool); function tradingOpen() external view returns (bool); function taxSwapMin() external view returns (uint256); function taxSwapMax() external view returns (uint256); function _isLiqPool(address) external view returns (bool); function taxRateBuy() external view returns (uint8); function taxRateSell() external view returns (uint8); function antiBotEnabled() external view returns (bool); function excludedFromAntiBot(address) external view returns (bool); function _lastSwapBlock(address) external view returns (uint256); function taxWallet() external view returns (address); event TokensAirdropped(uint256 totalWallets, uint256 totalTokens); event TokensBurned(address indexed burnedByWallet, uint256 tokenAmount); event TaxWalletChanged(address newTaxWallet); event TaxRateChanged(uint8 newBuyTax, uint8 newSellTax); function initLP() external; function enableTrading() external; function burnTokens(uint256 amount) external; function enableAntiBot(bool isEnabled) external; function excludeFromAntiBot(address wallet, bool isExcluded) external; function excludeFromFees(address wallet, bool isExcluded) external; function adjustTaxRate(uint8 newBuyTax, uint8 newSellTax) external; function setTaxWallet(address newTaxWallet) external; function taxSwapSettings(uint32 minValue, uint32 minDivider, uint32 maxValue, uint32 maxDivider) external; function totalSupply() external view returns (uint256); function decimals() external view returns (uint8); function symbol() external view returns (string memory); function name() external view returns (string memory); function getOwner() external view returns (address); function balanceOf(address account) external view returns (uint256); function transfer(address recipient, uint256 amount) external returns (bool); function allowance(address _owner, address spender) external view returns (uint256); function approve(address spender, uint256 amount) external returns (bool); function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); }
//SPDX-License-Identifier: MIT pragma solidity >=0.8.9; interface ITreasury { function deposit( uint256 _amount, address _token ) external; function depositEther() external payable; function withdraw( uint256 _amount, address _token ) external; function withdrawTo( uint256 _amount, address _token, address _to ) external; function withdrawEther( uint256 _amount ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; import "../interfaces/IAuthority.sol"; /// @dev Reasoning for this contract = modifiers literaly copy code /// instead of pointing towards the logic to execute. Over many /// functions this bloats contract size unnecessarily. /// imho modifiers are a meme. abstract contract AccessControlled { /* ========== EVENTS ========== */ event AuthorityUpdated(IAuthority authority); /* ========== STATE VARIABLES ========== */ IAuthority public authority; /* ========== Constructor ========== */ constructor(IAuthority _authority) { require(address(_authority) != address(0), "Authority cannot be zero address"); authority = _authority; emit AuthorityUpdated(_authority); } /* ========== "MODIFIERS" ========== */ modifier onlyGovernor { _onlyGovernor(); _; } modifier onlyGuardian { _onlyGuardian(); _; } modifier onlyPolicy { _onlyPolicy(); _; } modifier onlyVault { _onlyVault(); _; } modifier onlyGlobalRole(bytes32 _role){ _onlyRole(_role); _; } /* ========== GOV ONLY ========== */ function initializeAuthority(IAuthority _newAuthority) internal { require(authority == IAuthority(address(0)), "AUTHORITY_INITIALIZED"); authority = _newAuthority; emit AuthorityUpdated(_newAuthority); } function setAuthority(IAuthority _newAuthority) external { _onlyGovernor(); authority = _newAuthority; emit AuthorityUpdated(_newAuthority); } /* ========== INTERNAL CHECKS ========== */ function _onlyGovernor() internal view { require(msg.sender == authority.governor(), "UNAUTHORIZED"); } function _onlyGuardian() internal view { require(msg.sender == authority.guardian(), "UNAUTHORIZED"); } function _onlyPolicy() internal view { require(msg.sender == authority.policy(), "UNAUTHORIZED"); } function _onlyVault() internal view { require(msg.sender == authority.vault(), "UNAUTHORIZED"); } function _onlyRole(bytes32 _role) internal view { require(authority.roles(msg.sender) == _role, "UNAUTHORIZED"); } }
{ "metadata": { "bytecodeHash": "none", "useLiteralContent": true }, "optimizer": { "enabled": true, "runs": 800 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_authority","type":"address"},{"internalType":"address","name":"_konduxERC20","type":"address"},{"internalType":"address","name":"_treasury","type":"address"},{"internalType":"address","name":"_konduxERC721Founders","type":"address"},{"internalType":"address","name":"_konduxERC721kNFT","type":"address"},{"internalType":"address","name":"_helixERC20","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract IAuthority","name":"authority","type":"address"}],"name":"AuthorityUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Compound","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"token","type":"address"}],"name":"NewAPR","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"bool","name":"authorized","type":"bool"}],"name":"NewAuthorizedERC20","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"token","type":"address"}],"name":"NewCompoundFreq","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"token","type":"address"}],"name":"NewDivisorERC20","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"token","type":"address"}],"name":"NewFoundersRewardBoost","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"helixERC20","type":"address"}],"name":"NewHelixERC20","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"token","type":"address"}],"name":"NewKNFTRewardBoost","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"konduxERC721Founders","type":"address"}],"name":"NewKonduxERC721Founders","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"konduxERC721kNFT","type":"address"}],"name":"NewKonduxERC721kNFT","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"token","type":"address"}],"name":"NewMinStake","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"token","type":"address"}],"name":"NewRatio","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"treasury","type":"address"}],"name":"NewTreasury","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"token","type":"address"}],"name":"NewWithdrawalFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"netRewards","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fees","type":"uint256"}],"name":"Reward","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Stake","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Unstake","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"liquidAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fees","type":"uint256"}],"name":"Withdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"staker","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WithdrawAll","type":"event"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_apr","type":"uint256"},{"internalType":"uint256","name":"_compoundFreq","type":"uint256"},{"internalType":"uint256","name":"_withdrawalFee","type":"uint256"},{"internalType":"uint256","name":"_foundersRewardBoost","type":"uint256"},{"internalType":"uint256","name":"_kNFTRewardBoost","type":"uint256"},{"internalType":"uint256","name":"_ratio","type":"uint256"},{"internalType":"uint256","name":"_minStake","type":"uint256"}],"name":"addNewStakingToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"allowedDnaVersions","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"aprERC20","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"authority","outputs":[{"internalType":"contract IAuthority","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"authorizedERC20","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_staker","type":"address"},{"internalType":"uint256","name":"_stakeId","type":"uint256"}],"name":"calculateBoostPercentage","outputs":[{"internalType":"uint256","name":"boostPercentage","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_staker","type":"address"},{"internalType":"uint256","name":"_stakeId","type":"uint256"}],"name":"calculateKNFTBoostPercentage","outputs":[{"internalType":"uint256","name":"boostPercentage","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_staker","type":"address"}],"name":"calculateMaxKNFTBoostPercentage","outputs":[{"internalType":"uint256","name":"boostPercentage","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_staker","type":"address"},{"internalType":"uint256","name":"_depositId","type":"uint256"}],"name":"calculateRewards","outputs":[{"internalType":"uint256","name":"rewards","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_depositId","type":"uint256"}],"name":"claimRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"compoundFreqERC20","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_depositId","type":"uint256"}],"name":"compoundRewardsTimer","outputs":[{"internalType":"uint256","name":"remainingTime","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"decimalsERC20","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint8","name":"_timelock","type":"uint8"},{"internalType":"address","name":"_token","type":"address"}],"name":"deposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"divisorERC20","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_depositId","type":"uint256"}],"name":"earlyUnstake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"earlyWithdrawalPenalty","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"foundersRewardBoostERC20","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenId","type":"address"}],"name":"getAPR","outputs":[{"internalType":"uint256","name":"_rewardsPerHour","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_dnaVersion","type":"uint256"}],"name":"getAllowedDnaVersion","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"getDecimalsERC20","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_staker","type":"address"},{"internalType":"uint256","name":"_stakeId","type":"uint256"}],"name":"getDepositDetails","outputs":[{"internalType":"uint256","name":"_timelock","type":"uint256"},{"internalType":"uint256","name":"_depositTimestamp","type":"uint256"},{"internalType":"uint8","name":"_timelockCategory","type":"uint8"},{"internalType":"uint256","name":"_stake","type":"uint256"},{"internalType":"uint256","name":"_unclaimedRewards","type":"uint256"},{"internalType":"uint256","name":"_boostPercentage","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"getDepositIds","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_depositId","type":"uint256"}],"name":"getDepositInfo","outputs":[{"internalType":"uint256","name":"_stake","type":"uint256"},{"internalType":"uint256","name":"_unclaimedRewards","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_depositId","type":"uint256"}],"name":"getDepositRatioERC20","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_depositId","type":"uint256"}],"name":"getDepositTimestamp","outputs":[{"internalType":"uint256","name":"_depositTimestamp","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"getDivisorERC20","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"getEarlyWithdrawalPenalty","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenId","type":"address"}],"name":"getFoundersRewardBoost","outputs":[{"internalType":"uint256","name":"_foundersRewardBoost","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_staker","type":"address"}],"name":"getMaxTop5BonusesAndIds","outputs":[{"internalType":"uint256[]","name":"top5Bonuses","type":"uint256[]"},{"internalType":"uint256[]","name":"top5Ids","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenId","type":"address"}],"name":"getMinStake","outputs":[{"internalType":"uint256","name":"_minStake","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"getRatioERC20","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_depositId","type":"uint256"}],"name":"getStakedAmount","outputs":[{"internalType":"uint256","name":"_deposited","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_depositId","type":"uint256"}],"name":"getTimeOfLastUpdate","outputs":[{"internalType":"uint256","name":"_timeOfLastUpdate","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_depositId","type":"uint256"}],"name":"getTimelock","outputs":[{"internalType":"uint256","name":"_timelock","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_depositId","type":"uint256"}],"name":"getTimelockCategory","outputs":[{"internalType":"uint8","name":"_timelockCategory","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_category","type":"uint256"}],"name":"getTimelockCategoryBoost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_staker","type":"address"},{"internalType":"uint256","name":"_stakeId","type":"uint256"}],"name":"getTop5BonusesAndIds","outputs":[{"internalType":"uint256[]","name":"top5Bonuses","type":"uint256[]"},{"internalType":"uint256[]","name":"top5Ids","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"getTotalRewards","outputs":[{"internalType":"uint256","name":"_totalRewards","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"getTotalStaked","outputs":[{"internalType":"uint256","name":"_totalStaked","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"getTotalWithdrawalFees","outputs":[{"internalType":"uint256","name":"_totalWithdrawalFees","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"address","name":"_token","type":"address"}],"name":"getUserTotalRewardsByCoin","outputs":[{"internalType":"uint256","name":"_totalRewards","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"address","name":"_token","type":"address"}],"name":"getUserTotalStakedByCoin","outputs":[{"internalType":"uint256","name":"_totalStaked","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenId","type":"address"}],"name":"getWithdrawalFee","outputs":[{"internalType":"uint256","name":"_withdrawalFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenId","type":"address"}],"name":"getkNFTRewardBoost","outputs":[{"internalType":"uint256","name":"_kNFTRewardBoost","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"helixERC20","outputs":[{"internalType":"contract IHelix","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"kNFTRewardBoostERC20","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"konduxERC721Founders","outputs":[{"internalType":"contract IERC721","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"konduxERC721kNFT","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"minStakeERC20","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"ratioERC20","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_apr","type":"uint256"},{"internalType":"address","name":"_tokenId","type":"address"}],"name":"setAPR","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_dnaVersion","type":"uint256"},{"internalType":"bool","name":"_allowed","type":"bool"}],"name":"setAllowedDnaVersion","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IAuthority","name":"_newAuthority","type":"address"}],"name":"setAuthority","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"bool","name":"_authorized","type":"bool"}],"name":"setAuthorizedERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_compoundFreq","type":"uint256"},{"internalType":"address","name":"_tokenId","type":"address"}],"name":"setCompoundFreq","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_decimals","type":"uint8"},{"internalType":"address","name":"_tokenId","type":"address"}],"name":"setDecimalsERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_divisor","type":"uint256"},{"internalType":"address","name":"_tokenId","type":"address"}],"name":"setDivisorERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"penaltyPercentage","type":"uint256"}],"name":"setEarlyWithdrawalPenalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_foundersRewardBoost","type":"uint256"},{"internalType":"address","name":"_tokenId","type":"address"}],"name":"setFoundersRewardBoost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_helix","type":"address"}],"name":"setHelixERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_konduxERC721Founders","type":"address"}],"name":"setKonduxERC721Founders","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_konduxERC721kNFT","type":"address"}],"name":"setKonduxERC721kNFT","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minStake","type":"uint256"},{"internalType":"address","name":"_tokenId","type":"address"}],"name":"setMinStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_ratio","type":"uint256"},{"internalType":"address","name":"_tokenId","type":"address"}],"name":"setRatio","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_category","type":"uint256"},{"internalType":"uint256","name":"_boost","type":"uint256"}],"name":"setTimelockCategoryBoost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_treasury","type":"address"}],"name":"setTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_withdrawalFee","type":"uint256"},{"internalType":"address","name":"_tokenId","type":"address"}],"name":"setWithdrawalFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_kNFTRewardBoost","type":"uint256"},{"internalType":"address","name":"_tokenId","type":"address"}],"name":"setkNFTRewardBoost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_depositId","type":"uint256"}],"name":"stakeRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"timelockCategoryBoost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"","type":"uint8"}],"name":"timelockDurations","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"totalRewarded","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"totalStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"totalWithdrawalFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"contract ITreasury","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"userDeposits","outputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"staker","type":"address"},{"internalType":"uint256","name":"deposited","type":"uint256"},{"internalType":"uint256","name":"redeemed","type":"uint256"},{"internalType":"uint256","name":"timeOfLastUpdate","type":"uint256"},{"internalType":"uint256","name":"lastDepositTime","type":"uint256"},{"internalType":"uint256","name":"unclaimedRewards","type":"uint256"},{"internalType":"uint256","name":"timelock","type":"uint256"},{"internalType":"uint8","name":"timelockCategory","type":"uint8"},{"internalType":"uint256","name":"ratioERC20","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"userDepositsIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"userTotalRewardedByCoin","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"userTotalStakedByCoin","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_depositId","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_depositId","type":"uint256"}],"name":"withdrawAndClaim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"withdrawalFeeERC20","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b506040516200689a3803806200689a83398101604081905262000034916200122b565b856001600160a01b038116620000915760405162461bcd60e51b815260206004820181905260248201527f417574686f726974792063616e6e6f74206265207a65726f206164647265737360448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0383169081179091556040519081527f2f658b440c35314f52658ea8a740e05b284cdc84dc9ae01e891f21b8933e7cad9060200160405180910390a1506001600160a01b0385166200013b5760405162461bcd60e51b815260206004820152601f60248201527f4b6f6e6475782045524332302061646472657373206973206e6f742073657400604482015260640162000088565b6001600160a01b038416620001935760405162461bcd60e51b815260206004820152601b60248201527f54726561737572792061646472657373206973206e6f74207365740000000000604482015260640162000088565b6001600160a01b038316620001fd5760405162461bcd60e51b815260206004820152602960248201527f4b6f6e6475782045524337323120466f756e64657273206164647265737320696044820152681cc81b9bdd081cd95d60ba1b606482015260840162000088565b6001600160a01b038216620002635760405162461bcd60e51b815260206004820152602560248201527f4b6f6e64757820455243373231206b4e46542061646472657373206973206e6f6044820152641d081cd95d60da1b606482015260840162000088565b6001600160a01b038116620002bb5760405162461bcd60e51b815260206004820152601e60248201527f48656c69782045524332302061646472657373206973206e6f74207365740000604482015260640162000088565b601880546001600160a01b038086166001600160a01b0319928316179092556019805485841690831617905560178054848416908316179055601a805492871692909116919091179055601660205262278d007f0263c2b778d062355049effc2dece97bc6547ff8a88a3258daa512061c2153dd556276a7007f4c4dc693d7db52f85fe052106f4b4b920e78e8ef37dee82878a60ab8585faf495562ed4e007fcaff291fe014adc6b72a172705750b4cabe8f8667664d2924a166caab28856485560036000526301e133807ff06d282f967055cb1eee17e04aa005b9682a620f4bbcfaee55ba78607a3d87ae55620003b66127108662000561565b620003c3606486620005f8565b620003d16103e88662000709565b620003df6101f486620007a0565b620003ee629896808662000837565b620003fb601986620008ce565b6200040a620151808662000965565b6200041861271086620009fc565b6200042585600a62000a93565b620004336001606462000b68565b62000442600261012c62000b68565b62000451600361038462000b68565b6200045e60018062000b84565b6017546040805163313ce56760e01b81529051620004d8926001600160a01b03169163313ce5679160048083019260209291908290030181865afa158015620004ab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620004d19190620012ac565b8262000bae565b62000548856001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200051b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620005419190620012ac565b8662000bae565b6200055585600162000c2a565b50505050505062001310565b6200056b62001143565b6001600160a01b038116620005b25760405162461bcd60e51b815260206004820152601860248201526000805160206200687a833981519152604482015260640162000088565b6001600160a01b0381166000818152601460205260408082208590555184917f6a437d814668577dce2f82ae56ed67161e12e20b59b9464687859d6a2ce0faa591a35050565b6200060262001143565b6001600160a01b038116620006495760405162461bcd60e51b815260206004820152601860248201526000805160206200687a833981519152604482015260640162000088565b6001600160a01b038116600090815260146020526040902054821115620006c35760405162461bcd60e51b815260206004820152602760248201527f5769746864726177616c206665652063616e6e6f74206265206d6f7265207468604482015266616e203130302560c81b606482015260840162000088565b6001600160a01b0381166000818152600860205260408082208590555184917f5d5169bb1fbf418e612b1934f181b6ce300a1aad27fdb0e6f6aadbd96f50bb8f91a35050565b6200071362001143565b6001600160a01b0381166200075a5760405162461bcd60e51b815260206004820152601860248201526000805160206200687a833981519152604482015260640162000088565b6001600160a01b0381166000818152600960205260408082208590555184917f1677c34b69a09796446af7a4c75943a1bb36202c16eb82199ef7d37d0ee4b28891a35050565b620007aa62001143565b6001600160a01b038116620007f15760405162461bcd60e51b815260206004820152601860248201526000805160206200687a833981519152604482015260640162000088565b6001600160a01b0381166000818152600a60205260408082208590555184917f11ef1060a695a1277b08edcbb2c364d43d4eb52f1060daaabf0df445cb6cdfdf91a35050565b6200084162001143565b6001600160a01b038116620008885760405162461bcd60e51b815260206004820152601860248201526000805160206200687a833981519152604482015260640162000088565b6001600160a01b0381166000818152600560205260408082208590555184917fef3cb734d88702dbb1c3bc381c52176876be95e70b66d3970d16653ee992a6c291a35050565b620008d862001143565b6001600160a01b0381166200091f5760405162461bcd60e51b815260206004820152601860248201526000805160206200687a833981519152604482015260640162000088565b6001600160a01b0381166000818152600760205260408082208590555184917fef97689adaec5b60041d413c3baef6876d5d01bb6c17b60cc980e2e244ef851791a35050565b6200096f62001143565b6001600160a01b038116620009b65760405162461bcd60e51b815260206004820152601860248201526000805160206200687a833981519152604482015260640162000088565b6001600160a01b0381166000818152600660205260408082208590555184917fd0d3d840363c3a773f4578f92d7914f6b37985570c79ee2889d69d7d8f12c29591a35050565b62000a0662001143565b6001600160a01b03811662000a4d5760405162461bcd60e51b815260206004820152601860248201526000805160206200687a833981519152604482015260640162000088565b6001600160a01b0381166000818152600b60205260408082208590555184917f62b574cc62ed3db0ae736cb4349346a234832cc8b215c6423fd67505addc2ffa91a35050565b62000a9d62001143565b6001600160a01b03821662000ae45760405162461bcd60e51b815260206004820152601860248201526000805160206200687a833981519152604482015260640162000088565b606481111562000b4c5760405162461bcd60e51b815260206004820152602c60248201527f50656e616c74792070657263656e74616765206d75737420626520626574776560448201526b0656e203020616e64203130360a41b606482015260840162000088565b6001600160a01b03909116600090815260126020526040902055565b62000b7262001143565b60009182526013602052604090912055565b62000b8e62001143565b600091825260156020526040909120805460ff1916911515919091179055565b62000bb862001143565b6001600160a01b03811662000bff5760405162461bcd60e51b815260206004820152601860248201526000805160206200687a833981519152604482015260640162000088565b6001600160a01b03166000908152600c60205260409020805460ff191660ff92909216919091179055565b6001600160a01b03821662000c825760405162461bcd60e51b815260206004820152601b60248201527f546f6b656e20616464726573732063616e6e6f74206265203078300000000000604482015260640162000088565b801515600103620010ef576001600160a01b03821660009081526007602052604090205462000d045760405162461bcd60e51b815260206004820152602760248201527f526577617264732070657220686f7572206d75737420626520677265617465726044820152660207468616e20360cc1b606482015260840162000088565b6001600160a01b03821660009081526006602052604090205462000d7d5760405162461bcd60e51b815260206004820152602960248201527f436f6d706f756e64206672657175656e6379206d75737420626520677265617460448201526806572207468616e20360bc1b606482015260840162000088565b6001600160a01b03821660009081526008602052604090205462000df25760405162461bcd60e51b815260206004820152602560248201527f5769746864726177616c20666565206d75737420626520677265617465722074604482015264068616e20360dc1b606482015260840162000088565b6001600160a01b03821660009081526009602052604090205462000e6e5760405162461bcd60e51b815260206004820152602c60248201527f466f756e646572732072657761726420626f6f7374206d75737420626520677260448201526b06561746572207468616e20360a41b606482015260840162000088565b6001600160a01b0382166000908152600a602052604090205462000ee65760405162461bcd60e51b815260206004820152602860248201527f6b4e46542072657761726420626f6f7374206d75737420626520677265617465604482015267072207468616e20360c41b606482015260840162000088565b6001600160a01b0382166000908152600b602052604090205462000f4d5760405162461bcd60e51b815260206004820152601c60248201527f526174696f206d7573742062652067726561746572207468616e203000000000604482015260640162000088565b6001600160a01b03821660009081526005602052604090205462000fc05760405162461bcd60e51b8152602060048201526024808201527f4d696e696d756d207374616b65206d75737420626520677265617465722074686044820152630616e20360e41b606482015260840162000088565b6001600160a01b038216600090815260146020526040902054620010275760405162461bcd60e51b815260206004820152601e60248201527f44697669736f72206d7573742062652067726561746572207468616e20300000604482015260640162000088565b6000826001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562001068573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200108e9190620012d8565b11620010ef5760405162461bcd60e51b815260206004820152602960248201527f546f6b656e20746f74616c20737570706c79206d75737420626520677265617460448201526806572207468616e20360bc1b606482015260840162000088565b6001600160a01b038216600081815260046020526040808220805460ff191685151590811790915590519092917f59261974a183535ca20bb33ae77db42c679a079844739a2e10f0b6ecb847379a91a35050565b60008054906101000a90046001600160a01b03166001600160a01b0316630c340a246040518163ffffffff1660e01b8152600401602060405180830381865afa15801562001195573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620011bb9190620012f2565b6001600160a01b0316336001600160a01b0316146200120c5760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b604482015260640162000088565b565b80516001600160a01b03811681146200122657600080fd5b919050565b60008060008060008060c087890312156200124557600080fd5b62001250876200120e565b955062001260602088016200120e565b945062001270604088016200120e565b935062001280606088016200120e565b925062001290608088016200120e565b9150620012a060a088016200120e565b90509295509295509295565b600060208284031215620012bf57600080fd5b815160ff81168114620012d157600080fd5b9392505050565b600060208284031215620012eb57600080fd5b5051919050565b6000602082840312156200130557600080fd5b620012d1826200120e565b61555a80620013206000396000f3fe608060405234801561001057600080fd5b50600436106105a15760003560e01c806384d3d586116102ed578063d55111c511610191578063f0d33cad116100ee578063f384fe76116100a2578063fb68d53b1161007c578063fb68d53b14610f99578063fe1686b814610fd3578063fe31b2281461100d57600080fd5b8063f384fe7614610f30578063f91159e314610f50578063fad68d1f14610f7957600080fd5b8063f16b41f4116100d3578063f16b41f414610e2a578063f19d684914610ef4578063f2760e9d14610f0757600080fd5b8063f0d33cad14610deb578063f0f4426014610e1757600080fd5b8063e519cf1711610145578063ec6401531161012a578063ec64015314610da2578063f02842a514610db5578063f02d4a4514610dd857600080fd5b8063e519cf1714610d59578063ea425a6d14610d8257600080fd5b8063dad775b111610176578063dad775b114610d0a578063dd2a8b1114610d1d578063e37d47e414610d4657600080fd5b8063d55111c514610cd7578063d6b9243414610cea57600080fd5b8063b54b9c881161024a578063bf811fbc116101fe578063c706fee5116101d8578063c706fee514610c88578063cf717c8c14610cb1578063cfb656a514610cc457600080fd5b8063bf811fbc14610c2c578063c39ccf8814610c3f578063c5ebc2f714610c6857600080fd5b8063ba5771481161022f578063ba57714814610bf3578063beb8314c14610c06578063bf7e214f14610c1957600080fd5b8063b54b9c8814610bb0578063b6740c3b14610bd057600080fd5b80639bfd8d61116102a1578063a55dfa1c11610286578063a55dfa1c14610b77578063a9b2940714610b8a578063aaa78db414610b9d57600080fd5b80639bfd8d6114610b44578063a13d507914610b6457600080fd5b806389d5e38a116102d257806389d5e38a14610b0b578063911ddf0a14610b1e57806396ce362714610b3157600080fd5b806384d3d58614610ad857806387eebaea14610af857600080fd5b80634715f40c116104545780635a5392be116103b157806372aa9d91116103655780637b16c5431161033f5780637b16c54314610a7a5780637bf7f3d314610aa55780637cbfd14414610ab857600080fd5b806372aa9d9114610a3457806378e2816b14610a545780637a9e5e4b14610a6757600080fd5b80635dfa4596116103965780635dfa4596146109d657806361d027b314610a015780636e3c115414610a1457600080fd5b80635a5392be146109a05780635cd3667e146109c357600080fd5b80635385689c116104085780635722dee0116103ed5780635722dee014610931578063580e26a11461095a57806359b0e5901461097d57600080fd5b80635385689c146108e6578063546f2b661461091157600080fd5b80634a912ce5116104395780634a912ce5146108785780634e781513146108ab5780635328c2bf146108be57600080fd5b80634715f40c1461083c5780634774dc931461086557600080fd5b80632bcf161c116105025780633d0132e7116104b6578063404d221a1161049b578063404d221a14610803578063441a3e70146108165780634477c9741461082957600080fd5b80633d0132e7146107a85780633dc60a70146107f057600080fd5b806338c26d18116104e757806338c26d181461072d5780633a46a46d146107655780633ae5713d1461078557600080fd5b80632bcf161c146106f1578063336cada81461071a57600080fd5b8063171f9ce4116105595780631c5122d91161053e5780631c5122d9146106955780631e78e9a2146106be5780631f6514db146106de57600080fd5b8063171f9ce41461065f57806319720be11461067257600080fd5b80630962ef791161058a5780630962ef79146105fe57806310b1843814610613578063151a63491461063657600080fd5b80630399be55146105a657806306811c92146105d0575b600080fd5b6105b96105b4366004615030565b61102d565b6040516105c7929190615097565b60405180910390f35b6105f06105de3660046150c5565b60076020526000908152604090205481565b6040519081526020016105c7565b61061161060c3660046150e9565b611409565b005b6105f06106213660046150e9565b60009081526003602052604090206007015490565b6105f06106443660046150c5565b6001600160a01b031660009081526011602052604090205490565b61061161066d366004615102565b611765565b6105f06106803660046150e9565b60009081526003602052604090206005015490565b6105f06106a33660046150c5565b6001600160a01b031660009081526007602052604090205490565b6105f06106cc3660046150c5565b600a6020526000908152604090205481565b6106116106ec366004615102565b6117f7565b6105f06106ff3660046150c5565b6001600160a01b03166000908152600f602052604090205490565b610611610728366004615102565b611889565b61075361073b3660046150e9565b60009081526003602052604090206008015460ff1690565b60405160ff90911681526020016105c7565b6105f06107733660046150c5565b600b6020526000908152604090205481565b6107536107933660046150c5565b600c6020526000908152604090205460ff1681565b6107bb6107b6366004615030565b61191b565b60408051968752602087019590955260ff909316938501939093526060840152608083019190915260a082015260c0016105c7565b6105f06107fe366004615030565b611984565b610611610811366004615102565b611b79565b610611610824366004615132565b611c0b565b6106116108373660046150e9565b61236d565b6105f061084a3660046150c5565b6001600160a01b031660009081526009602052604090205490565b6105f0610873366004615163565b6125ec565b61089b6108863660046150e9565b60156020526000908152604090205460ff1681565b60405190151581526020016105c7565b6106116108b9366004615132565b612ca6565b6108d16108cc3660046150e9565b6134c9565b604080519283526020830191909152016105c7565b6019546108f9906001600160a01b031681565b6040516001600160a01b0390911681526020016105c7565b6105f061091f3660046150c5565b60096020526000908152604090205481565b6105f061093f3660046150c5565b6001600160a01b031660009081526008602052604090205490565b61089b6109683660046150c5565b60046020526000908152604090205460ff1681565b6105f061098b3660046150e9565b60009081526003602052604090206004015490565b6105f06109ae3660046150e9565b60009081526003602052604090206002015490565b6106116109d1366004615132565b613500565b6105f06109e43660046151a5565b600e60209081526000928352604080842090915290825290205481565b601a546108f9906001600160a01b031681565b6105f0610a223660046150e9565b60009081526013602052604090205490565b6105f0610a423660046150c5565b60056020526000908152604090205481565b610611610a623660046150c5565b61351a565b610611610a753660046150c5565b6135c2565b6105f0610a883660046151a5565b601060209081526000928352604080842090915290825290205481565b610611610ab33660046151e1565b61361e565b6105f0610ac63660046150c5565b60116020526000908152604090205481565b6105f0610ae63660046150c5565b60126020526000908152604090205481565b610611610b06366004615132565b613678565b6105f0610b193660046150c5565b61368b565b610611610b2c36600461520f565b6136e6565b610611610b3f366004615030565b613b6b565b6105f0610b523660046150c5565b600d6020526000908152604090205481565b610611610b72366004615102565b613c4a565b6105f0610b853660046150e9565b613cdc565b6017546108f9906001600160a01b031681565b610611610bab36600461526d565b613d3e565b6105f0610bbe3660046150c5565b60086020526000908152604090205481565b6105f0610bde3660046150e9565b60009081526003602052604090206009015490565b6105f0610c01366004615030565b613d66565b6105f0610c14366004615030565b613d97565b6000546108f9906001600160a01b031681565b610611610c3a3660046150c5565b613f02565b6105f0610c4d3660046150c5565b6001600160a01b031660009081526005602052604090205490565b610c7b610c763660046150c5565b613faa565b6040516105c79190615292565b6105f0610c963660046150c5565b6001600160a01b03166000908152600b602052604090205490565b610611610cbf366004615102565b614016565b610611610cd23660046150c5565b614136565b6018546108f9906001600160a01b031681565b6105f0610cf83660046150c5565b60146020526000908152604090205481565b610611610d18366004615102565b6141de565b6105f0610d2b3660046150c5565b6001600160a01b03166000908152600d602052604090205490565b610611610d54366004615102565b614270565b6105f0610d673660046150c5565b6001600160a01b03166000908152600a602052604090205490565b6105f0610d903660046150c5565b60066020526000908152604090205481565b6105f0610db0366004615030565b614302565b61089b610dc33660046150e9565b60009081526015602052604090205460ff1690565b6105b9610de63660046150c5565b61435f565b610753610df93660046150c5565b6001600160a01b03166000908152600c602052604090205460ff1690565b610611610e253660046150c5565b6146ad565b610e9c610e383660046150e9565b600360208190526000918252604090912080546001820154600283015493830154600484015460058501546006860154600787015460088801546009909801546001600160a01b0397881699969097169795969495939492939192909160ff16908a565b604080516001600160a01b039b8c1681529a90991660208b0152978901969096526060880194909452608087019290925260a086015260c085015260e084015260ff16610100830152610120820152610140016105c7565b610611610f023660046152a5565b614755565b6105f0610f153660046150c5565b6001600160a01b031660009081526012602052604090205490565b6105f0610f3e3660046150c5565b600f6020526000908152604090205481565b6105f0610f5e3660046150c5565b6001600160a01b031660009081526014602052604090205490565b6105f0610f873660046150e9565b60136020526000908152604090205481565b6105f0610fa73660046151a5565b6001600160a01b0380821660009081526010602090815260408083209386168352929052205492915050565b6105f0610fe13660046151a5565b6001600160a01b038082166000908152600e602090815260408083209386168352929052205492915050565b6105f061101b3660046152c3565b60166020526000908152604090205481565b6019546040516370a0823160e01b81526001600160a01b0384811660048301526060928392600092909116906370a0823190602401602060405180830381865afa15801561107f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110a391906152e0565b60408051600580825260c082019092529192506020820160a080368337505060408051600580825260c0820190925292955090506020820160a08036833701905050915060005b8181101561140057601954604051632f745c5960e01b81526001600160a01b038881166004830152602482018490526000921690632f745c5990604401602060405180830381865afa158015611144573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061116891906152e0565b600087815260036020526040908190206005015460195491516319d42f2f60e21b815260048101849052929350916001600160a01b0390911690636750bcbc90602401602060405180830381865afa1580156111c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111ec91906152e0565b11156111f857506113ee565b60195460405163032bbfbd60e21b81526004810183905260006024820181905260016044830152916001600160a01b031690630caefef490606401602060405180830381865afa158015611250573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061127491906152e0565b60008181526015602052604090205490915060ff166112945750506113ee565b60195460405163032bbfbd60e21b81526004810184905260016024820152600260448201526000916001600160a01b031690630caefef490606401602060405180830381865afa1580156112ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061131091906152e0565b61131b90606461530f565b9050600081121561132a575060005b60005b60058110156113e9578781815181106113485761134861533f565b60200260200101518211156113d757600088828151811061136b5761136b61533f565b60200260200101519050828983815181106113885761138861533f565b60200260200101818152505080925060008883815181106113ab576113ab61533f565b60200260200101519050858984815181106113c8576113c861533f565b60209081029190910101529450505b806113e181615355565b91505061132d565b505050505b806113f881615355565b9150506110ea565b50509250929050565b6000818152600360205260409020600101546001600160a01b031633146114855760405162461bcd60e51b815260206004820152602560248201527f596f7520617265206e6f7420746865206f776e6572206f6620746869732064656044820152641c1bdcda5d60da1b60648201526084015b60405180910390fd5b6000818152600360205260409020600701544210156114e65760405162461bcd60e51b815260206004820152601360248201527f54696d656c6f636b206e6f742070617373656400000000000000000000000000604482015260640161147c565b6000818152600360205260408120600601546115023384613d97565b61150c919061536e565b90506000811161155e5760405162461bcd60e51b815260206004820152601360248201527f596f752068617665206e6f207265776172647300000000000000000000000000604482015260640161147c565b600082815260036020908152604080832060068101849055426004820155546001600160a01b03168084526014835281842054600890935290832054909291906115aa90612710615381565b6115b49085615394565b6115be91906153ab565b905060006115cc8285615381565b9050826001600160a01b03166323b872dd60008054906101000a90046001600160a01b03166001600160a01b031663fbfa77cf6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561162e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061165291906153cd565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152336024820152604481018590526064016020604051808303816000875af11580156116a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116c991906153ea565b50600085815260036020526040902080546001909101546116f89184916001600160a01b0391821691166147cc565b6117226117058386615381565b6000878152600360205260409020546001600160a01b031661483a565b604080518381526020810183905233917f02a6a2be713fedf52f113c0a759f1c1a23a113476d9b1b1a2a453c910660de4e91015b60405180910390a25050505050565b61176d61486b565b6001600160a01b0381166117b15760405162461bcd60e51b8152602060048201526018602482015260008051602061552e833981519152604482015260640161147c565b6001600160a01b0381166000818152600b60205260408082208590555184917f62b574cc62ed3db0ae736cb4349346a234832cc8b215c6423fd67505addc2ffa91a35050565b6117ff61486b565b6001600160a01b0381166118435760405162461bcd60e51b8152602060048201526018602482015260008051602061552e833981519152604482015260640161147c565b6001600160a01b0381166000818152600960205260408082208590555184917f1677c34b69a09796446af7a4c75943a1bb36202c16eb82199ef7d37d0ee4b28891a35050565b61189161486b565b6001600160a01b0381166118d55760405162461bcd60e51b8152602060048201526018602482015260008051602061552e833981519152604482015260640161147c565b6001600160a01b0381166000818152600760205260408082208590555184917fef97689adaec5b60041d413c3baef6876d5d01bb6c17b60cc980e2e244ef851791a35050565b60008060008060008061193d8760009081526003602052604090206007015490565b60008881526003602052604090206005810154600890910154919750955060ff169350611969876134c9565b90935091506119788888611984565b90509295509295509295565b600081815260036020818152604080842081516101408101835281546001600160a01b0390811680835260018401548216838701526002840154838601529583015460608301526004808401546080840152600584015460a0840152600684015460c0840152600784015460e0840152600884015460ff1661010084015260099093015461012083015294865260149093528185205460185492516370a0823160e01b81528886169281019290925294929391909116906370a0823190602401602060405180830381865afa158015611a61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a8591906152e0565b1115611ab25780516001600160a01b0316600090815260096020526040902054611aaf908361536e565b91505b6019546040516370a0823160e01b81526001600160a01b03868116600483015260009216906370a0823190602401602060405180830381865afa158015611afd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b2191906152e0565b1115611b3e57611b318484614302565b611b3b908361536e565b91505b61010081015160ff1615611b715761010081015160ff16600090815260136020526040902054611b6e908361536e565b91505b505b92915050565b611b8161486b565b6001600160a01b038116611bc55760405162461bcd60e51b8152602060048201526018602482015260008051602061552e833981519152604482015260640161147c565b6001600160a01b0381166000818152600560205260408082208590555184917fef3cb734d88702dbb1c3bc381c52176876be95e70b66d3970d16653ee992a6c291a35050565b600081815260036020526040902060070154421015611c6c5760405162461bcd60e51b815260206004820152601360248201527f54696d656c6f636b206e6f742070617373656400000000000000000000000000604482015260640161147c565b6000818152600360205260409020600101546001600160a01b03163314611ce35760405162461bcd60e51b815260206004820152602560248201527f596f7520617265206e6f7420746865206f776e6572206f6620746869732064656044820152641c1bdcda5d60da1b606482015260840161147c565b600081815260036020526040902060020154821115611d4e5760405162461bcd60e51b815260206004820152602160248201527f43616e2774207769746864726177206d6f7265207468616e20796f75206861766044820152606560f81b606482015260840161147c565b6017546040516370a0823160e01b81523360048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015611d96573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dba91906152e0565b600082815260036020526040902060090154611dd69084615394565b1115611e4a5760405162461bcd60e51b815260206004820152603760248201527f43616e2774207769746864726177206d6f726520746f6b656e73207468616e2060448201527f74686520636f6c6c61746572616c20796f752068617665000000000000000000606482015260840161147c565b6000611e563383613d97565b905082600360008481526020019081526020016000206002016000828254611e7e9190615381565b909155505060008281526003602052604081204260048201556006018054839290611eaa90849061536e565b90915550506000828152600360209081526040808320546001600160a01b031683526014808352818420546008845291842054925290611eea9082615381565b611ef49086615394565b611efe91906153ab565b90506000611f0c8286615381565b6000858152600360209081526040808320549254815163fbfa77cf60e01b815291519495506001600160a01b03938416948794869463dd62ed3e94919093169263fbfa77cf926004808401938290030181865afa158015611f71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f9591906153cd565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152306024820152604401602060405180830381865afa158015611fdf573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061200391906152e0565b10156120a85760405162461bcd60e51b815260206004820152606260248201527f547265617375727920436f6e7472616374206e65656420746f20617070726f7660448201527f65205374616b696e6720436f6e747261637420746f207769746864726177207960648201527f6f757220746f6b656e73202d2d20706c656173652063616c6c20616e2041646d60848201526134b760f11b60a482015260c40161147c565b600085815260036020526040902080546001909101546120d69188916001600160a01b039182169116614942565b6000858152600360209081526040808320546001600160a01b039081168452600c90925280832054601754909216835282205460ff918216929116908183101561212e576121248383615407565b60ff169050612132565b5060005b6017546001600160a01b0316639dc29fac3361214f84600a615504565b60008c81526003602052604090206009015461216b908e615394565b6121759190615394565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b1580156121bb57600080fd5b505af11580156121cf573d6000803e3d6000fd5b50505050836001600160a01b03166323b872dd60008054906101000a90046001600160a01b03166001600160a01b031663fbfa77cf6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612233573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061225791906153cd565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152336024820152604481018990526064016020604051808303816000875af11580156122aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122ce91906153ea565b50600088815260036020526040902080546001909101546122fd9188916001600160a01b0391821691166147cc565b61232761230a878b615381565b60008a8152600360205260409020546001600160a01b031661483a565b604080518781526020810187905233917ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b568910160405180910390a2505050505050505050565b6000818152600360205260409020600101546001600160a01b031633146123e45760405162461bcd60e51b815260206004820152602560248201527f596f7520617265206e6f7420746865206f776e6572206f6620746869732064656044820152641c1bdcda5d60da1b606482015260840161147c565b6000818152600360205260408120600601546124003384613d97565b61240a919061536e565b90506000811161245c5760405162461bcd60e51b815260206004820152601460248201527f4e6f207265776172647320617661696c61626c65000000000000000000000000604482015260640161147c565b600082815260036020526040812060068101829055600201805483929061248490849061536e565b9091555050600082815260036020526040902042600482015580546001909101546124bd9183916001600160a01b039182169116614ab3565b6000828152600360209081526040808320546001600160a01b039081168452600c90925280832054601754909216835282205460ff91821692911690828211156125155761250b8383615407565b60ff169050612519565b5060005b6017546001600160a01b03166340c10f193361253684600a615504565b6000898152600360205260409020600901546125529089615394565b61255c9190615394565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b1580156125a257600080fd5b505af11580156125b6573d6000803e3d6000fd5b50506040518681523392507f169f1815ebdea059aac3bb00ec9a9594c7a5ffcb64a17e8392b5d84909a145569150602001611756565b60006001600160a01b0382166126325760405162461bcd60e51b8152602060048201526018602482015260008051602061552e833981519152604482015260640161147c565b6001600160a01b03821660009081526004602052604090205460ff1661269a5760405162461bcd60e51b815260206004820152601460248201527f546f6b656e206e6f7420617574686f72697a6564000000000000000000000000604482015260640161147c565b6001600160a01b0382166000908152600560205260409020548410156127105760405162461bcd60e51b815260206004820152602560248201527f416d6f756e7420736d616c6c6572207468616e206d696e696d696d756d2064656044820152641c1bdcda5d60da1b606482015260840161147c565b6040516370a0823160e01b8152336004820152829085906001600160a01b038316906370a0823190602401602060405180830381865afa158015612758573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061277c91906152e0565b10156127ca5760405162461bcd60e51b815260206004820152601d60248201527f43616e2774207374616b65206d6f7265207468616e20796f75206f776e000000604482015260640161147c565b604051636eb1769f60e11b815233600482015230602482015285906001600160a01b0383169063dd62ed3e90604401602060405180830381865afa158015612816573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061283a91906152e0565b10156128885760405162461bcd60e51b815260206004820152601160248201527f416c6c6f77616e6365206e6f7420736574000000000000000000000000000000604482015260640161147c565b60038460ff1611156128dc5760405162461bcd60e51b815260206004820152601060248201527f496e76616c69642074696d656c6f636b00000000000000000000000000000000604482015260640161147c565b60006128e760015490565b9050604051806101400160405280856001600160a01b03168152602001336001600160a01b031681526020018781526020016000815260200142815260200142815260200160008152602001601660008860ff1660ff1681526020019081526020016000205442612958919061536e565b815260ff8781166020808401919091526001600160a01b038881166000908152600b8352604080822054958101959095528681526003808452858220875181546001600160a01b0319908116918616919091178255888601516001808401805490931691909616179055878701516002808301919091556060890151928201929092556080880151600482015560a0880151600582015560c0880151600682015560e0880151600782015561010088015160088201805460ff191691909716179095556101209096015160099094019390935533808452948252928220805493840181558252902001829055612a519087908690614ab3565b6001600160a01b038085166000908152600c602052604080822054601754909316825281205460ff92831692169082821115612a9b57612a918383615407565b60ff169050612a9f565b5060005b846001600160a01b03166323b872dd3360008054906101000a90046001600160a01b03166001600160a01b031663fbfa77cf6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612b00573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b2491906153cd565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604481018c90526064016020604051808303816000875af1158015612b78573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b9c91906153ea565b506017546001600160a01b03166340c10f1933612bba84600a615504565b6001600160a01b038b166000908152600b6020526040902054612bdd908e615394565b612be79190615394565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015612c2d57600080fd5b505af1158015612c41573d6000803e3d6000fd5b50505050612c53600180546001019055565b604080516001600160a01b0389168152602081018b9052339186917ff7373f56c201647feae85a62d3cf56286ed3a43d20c5eb7f9883d6ea690ef7c0910160405180910390a35091979650505050505050565b6000818152600360205260409020600101546001600160a01b03163314612d1d5760405162461bcd60e51b815260206004820152602560248201527f596f7520617265206e6f7420746865206f776e6572206f6620746869732064656044820152641c1bdcda5d60da1b606482015260840161147c565b600081815260036020526040902060020154821115612d885760405162461bcd60e51b815260206004820152602160248201527f43616e2774207769746864726177206d6f7265207468616e20796f75206861766044820152606560f81b606482015260840161147c565b6017546040516370a0823160e01b81523360048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015612dd0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612df491906152e0565b600082815260036020526040902060090154612e109084615394565b1115612e845760405162461bcd60e51b815260206004820152603760248201527f43616e2774207769746864726177206d6f726520746f6b656e73207468616e2060448201527f74686520636f6c6c61746572616c20796f752068617665000000000000000000606482015260840161147c565b6000818152600360205260409020600701544210612ee45760405162461bcd60e51b815260206004820152601360248201527f54696d656c6f636b206861732070617373656400000000000000000000000000604482015260640161147c565b600081815260036020526040812060070154612f01904290615381565b600083815260036020526040812060058101546007909101549293509091612f299190615381565b90506000612f38826064615394565b6000858152600360209081526040808320546001600160a01b0316835260129091529020548490612f699088615394565b612f739190615394565b612f7d91906153ab565b905084811115612f8a5750835b80600003612fac576064612f9f866001615394565b612fa991906153ab565b90505b6000848152600360209081526040808320546001600160a01b031683526008909152812054612fdb908361536e565b90506000612fe98288615381565b90506000612ff78289615381565b90508760036000898152602001908152602001600020600201600082825461301f9190615381565b909155505060008781526003602090815260408083204260048083019190915590549354825163fbfa77cf60e01b815292516001600160a01b03958616958895879563dd62ed3e95929094169363fbfa77cf938184019390918290030181865afa158015613091573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130b591906153cd565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152306024820152604401602060405180830381865afa1580156130ff573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061312391906152e0565b10156131c85760405162461bcd60e51b815260206004820152606260248201527f547265617375727920436f6e7472616374206e65656420746f20617070726f7660448201527f65205374616b696e6720436f6e747261637420746f207769746864726177207960648201527f6f757220746f6b656e73202d2d20706c656173652063616c6c20616e2041646d60848201526134b760f11b60a482015260c40161147c565b600088815260036020526040902080546001909101546131f6918b916001600160a01b039182169116614942565b6017546001600160a01b039081166000908152600c60208181526040808420548d855260038352818520549095168452919052812054909160ff90811691161015613289576000898152600360209081526040808320546001600160a01b039081168452600c9092528083205460175490921683529091205461327f9160ff9081169116615407565b60ff16905061328d565b5060005b6017546001600160a01b0316639dc29fac336132aa84600a615504565b60008d8152600360205260409020600901546132c6908f615394565b6132d09190615394565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b15801561331657600080fd5b505af115801561332a573d6000803e3d6000fd5b50505050816001600160a01b03166323b872dd60008054906101000a90046001600160a01b03166001600160a01b031663fbfa77cf6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561338e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133b291906153cd565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152336024820152604481018790526064016020604051808303816000875af1158015613405573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061342991906153ea565b50600089815260036020526040902080546001909101546134589186916001600160a01b0391821691166147cc565b613482613465858c615381565b60008b8152600360205260409020546001600160a01b031661483a565b604080518581526020810185905233917ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b568910160405180910390a250505050505050505050565b600081815260036020526040812060028101546006909101549091906134ef3385613d97565b6134f9919061536e565b9050915091565b61350861486b565b60009182526013602052604090912055565b61352261486b565b6001600160a01b0381166135785760405162461bcd60e51b815260206004820152601e60248201527f466f756e6465727320616464726573732063616e6e6f74206265203078300000604482015260640161147c565b601880546001600160a01b0319166001600160a01b0383169081179091556040517f23008753c65029d55e051a14341d50cf19b808653ba432a5faeb07bd7865e25b90600090a250565b6135ca61486b565b600080546001600160a01b0319166001600160a01b0383169081179091556040519081527f2f658b440c35314f52658ea8a740e05b284cdc84dc9ae01e891f21b8933e7cad9060200160405180910390a150565b61362661486b565b6001600160a01b03821661366a5760405162461bcd60e51b8152602060048201526018602482015260008051602061552e833981519152604482015260640161147c565b6136748282614b17565b5050565b6136828282611c0b565b61367481611409565b6000806136978361435f565b50905060005b60058110156136df578181815181106136b8576136b861533f565b6020026020010151836136cb919061536e565b9250806136d781615355565b91505061369d565b5050919050565b6136ee61486b565b6001600160a01b0388166137445760405162461bcd60e51b815260206004820152601b60248201527f546f6b656e20616464726573732063616e6e6f74206265203078300000000000604482015260640161147c565b600087116137a45760405162461bcd60e51b815260206004820152602760248201527f526577617264732070657220686f7572206d75737420626520677265617465726044820152660207468616e20360cc1b606482015260840161147c565b600086116138065760405162461bcd60e51b815260206004820152602960248201527f436f6d706f756e64206672657175656e6379206d75737420626520677265617460448201526806572207468616e20360bc1b606482015260840161147c565b600085116138645760405162461bcd60e51b815260206004820152602560248201527f5769746864726177616c20666565206d75737420626520677265617465722074604482015264068616e20360dc1b606482015260840161147c565b600084116138c95760405162461bcd60e51b815260206004820152602c60248201527f466f756e646572732072657761726420626f6f7374206d75737420626520677260448201526b06561746572207468616e20360a41b606482015260840161147c565b6000831161392a5760405162461bcd60e51b815260206004820152602860248201527f6b4e46542072657761726420626f6f7374206d75737420626520677265617465604482015267072207468616e20360c41b606482015260840161147c565b6000821161397a5760405162461bcd60e51b815260206004820152601c60248201527f526174696f206d7573742062652067726561746572207468616e203000000000604482015260640161147c565b600081116139d65760405162461bcd60e51b8152602060048201526024808201527f4d696e696d756d207374616b65206d75737420626520677265617465722074686044820152630616e20360e41b606482015260840161147c565b6000886001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613a16573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a3a91906152e0565b11613a995760405162461bcd60e51b815260206004820152602960248201527f546f6b656e20746f74616c20737570706c79206d75737420626520677265617460448201526806572207468616e20360bc1b606482015260840161147c565b613aa5612710896141de565b613aaf84896117f7565b613ab98389613c4a565b613ac38789611889565b613acd8289611765565b613ad78589614016565b613ae18689614270565b613aeb8189611b79565b613b56886001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015613b2c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b509190615510565b89614755565b613b61886001614b17565b5050505050505050565b613b7361486b565b6001600160a01b038216613bb75760405162461bcd60e51b8152602060048201526018602482015260008051602061552e833981519152604482015260640161147c565b6064811115613c2e5760405162461bcd60e51b815260206004820152602c60248201527f50656e616c74792070657263656e74616765206d75737420626520626574776560448201527f656e203020616e64203130300000000000000000000000000000000000000000606482015260840161147c565b6001600160a01b03909116600090815260126020526040902055565b613c5261486b565b6001600160a01b038116613c965760405162461bcd60e51b8152602060048201526018602482015260008051602061552e833981519152604482015260640161147c565b6001600160a01b0381166000818152600a60205260408082208590555184917f11ef1060a695a1277b08edcbb2c364d43d4eb52f1060daaabf0df445cb6cdfdf91a35050565b6000818152600360209081526040808320600481015490546001600160a01b031684526006909252822054613d11818361536e565b4210613d21575060009392505050565b42613d2c828461536e565b613d369190615381565b949350505050565b613d4661486b565b600091825260156020526040909120805460ff1916911515919091179055565b60026020528160005260406000208181548110613d8257600080fd5b90600052602060002001600091509150505481565b600081815260036020818152604080842081516101408101835281546001600160a01b0390811682526001830154811694820185905260028301549382019390935293810154606085015260048101546080850152600581015460a0850152600681015460c0850152600781015460e0850152600881015460ff1661010085015260090154610120840152851614613e33576000915050611b73565b6000816080015142613e459190615381565b60408084015184516001600160a01b03166000908152600760205291822054929350919063bbf81e00613e788385615394565b613e8a90670de0b6b3a7640000615394565b613e9491906153ab565b90506000670de0b6b3a7640000613eab8387615394565b613eb591906153ab565b90506000613ec38a8a611984565b87516001600160a01b0316600090815260146020526040902054909150613eea8284615394565b613ef491906153ab565b9a9950505050505050505050565b613f0a61486b565b6001600160a01b038116613f605760405162461bcd60e51b815260206004820152601a60248201527f6b4e465420616464726573732063616e6e6f7420626520307830000000000000604482015260640161147c565b601980546001600160a01b0319166001600160a01b0383169081179091556040517fc8e08c5b2fa487609cdc92d5cfcc240f3c8fc73ac5e58fafc5d465d20aaaf31290600090a250565b6001600160a01b03811660009081526002602090815260409182902080548351818402810184019094528084526060939283018282801561400a57602002820191906000526020600020905b815481526020019060010190808311613ff6575b50505050509050919050565b61401e61486b565b6001600160a01b0381166140625760405162461bcd60e51b8152602060048201526018602482015260008051602061552e833981519152604482015260640161147c565b6001600160a01b0381166000908152601460205260409020548211156140f05760405162461bcd60e51b815260206004820152602760248201527f5769746864726177616c206665652063616e6e6f74206265206d6f726520746860448201527f616e203130302500000000000000000000000000000000000000000000000000606482015260840161147c565b6001600160a01b0381166000818152600860205260408082208590555184917f5d5169bb1fbf418e612b1934f181b6ce300a1aad27fdb0e6f6aadbd96f50bb8f91a35050565b61413e61486b565b6001600160a01b0381166141945760405162461bcd60e51b815260206004820152601b60248201527f48656c697820616464726573732063616e6e6f74206265203078300000000000604482015260640161147c565b601780546001600160a01b0319166001600160a01b0383169081179091556040517fdcbeffeaf77a19486e34d4b5fc3809913d1e7125a43b8dcdb17944ab2c17579090600090a250565b6141e661486b565b6001600160a01b03811661422a5760405162461bcd60e51b8152602060048201526018602482015260008051602061552e833981519152604482015260640161147c565b6001600160a01b0381166000818152601460205260408082208590555184917f6a437d814668577dce2f82ae56ed67161e12e20b59b9464687859d6a2ce0faa591a35050565b61427861486b565b6001600160a01b0381166142bc5760405162461bcd60e51b8152602060048201526018602482015260008051602061552e833981519152604482015260640161147c565b6001600160a01b0381166000818152600660205260408082208590555184917fd0d3d840363c3a773f4578f92d7914f6b37985570c79ee2889d69d7d8f12c29591a35050565b60008061430f848461102d565b50905060005b6005811015614357578181815181106143305761433061533f565b602002602001015183614343919061536e565b92508061434f81615355565b915050614315565b505092915050565b6019546040516370a0823160e01b81526001600160a01b0383811660048301526060928392600092909116906370a0823190602401602060405180830381865afa1580156143b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906143d591906152e0565b60408051600580825260c082019092529192506020820160a080368337505060408051600580825260c0820190925292955090506020820160a08036833701905050915060005b818110156146a657601954604051632f745c5960e01b81526001600160a01b038781166004830152602482018490526000921690632f745c5990604401602060405180830381865afa158015614476573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061449a91906152e0565b60195460405163032bbfbd60e21b815260048101839052600060248201819052600160448301529293506001600160a01b0390911690630caefef490606401602060405180830381865afa1580156144f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061451a91906152e0565b60008181526015602052604090205490915060ff1661453a575050614694565b60195460405163032bbfbd60e21b81526004810184905260016024820152600260448201526000916001600160a01b031690630caefef490606401602060405180830381865afa158015614592573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906145b691906152e0565b6145c190606461530f565b905060008112156145d0575060005b60005b600581101561468f578781815181106145ee576145ee61533f565b602002602001015182111561467d5760008882815181106146115761461161533f565b602002602001015190508289838151811061462e5761462e61533f565b60200260200101818152505080925060008883815181106146515761465161533f565b602002602001015190508589848151811061466e5761466e61533f565b60209081029190910101529450505b8061468781615355565b9150506145d3565b505050505b8061469e81615355565b91505061441c565b5050915091565b6146b561486b565b6001600160a01b03811661470b5760405162461bcd60e51b815260206004820152601e60248201527f547265617375727920616464726573732063616e6e6f74206265203078300000604482015260640161147c565b601a80546001600160a01b0319166001600160a01b0383169081179091556040517fafa147634b29e2c7bd53ce194256b9f41cfb9ba3036f2b822fdd1d965beea08690600090a250565b61475d61486b565b6001600160a01b0381166147a15760405162461bcd60e51b8152602060048201526018602482015260008051602061552e833981519152604482015260640161147c565b6001600160a01b03166000908152600c60205260409020805460ff191660ff92909216919091179055565b6001600160a01b0382166000908152600f6020526040812080548592906147f490849061536e565b90915550506001600160a01b0380831660009081526010602090815260408083209385168352929052908120805485929061483090849061536e565b9091555050505050565b6001600160a01b0381166000908152601160205260408120805484929061486290849061536e565b90915550505050565b60008054906101000a90046001600160a01b03166001600160a01b0316630c340a246040518163ffffffff1660e01b8152600401602060405180830381865afa1580156148bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906148e091906153cd565b6001600160a01b0316336001600160a01b0316146149405760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a45440000000000000000000000000000000000000000604482015260640161147c565b565b6001600160a01b0382166000908152600d60205260409020548311156149d05760405162461bcd60e51b815260206004820152602560248201527f5374616b696e673a204e6f7420656e6f756768207374616b65642028436f6e7460448201527f7261637429000000000000000000000000000000000000000000000000000000606482015260840161147c565b6001600160a01b038083166000908152600e6020908152604080832093851683529290522054831115614a4f5760405162461bcd60e51b815260206004820152602160248201527f5374616b696e673a204e6f7420656e6f756768207374616b65642028557365726044820152602960f81b606482015260840161147c565b6001600160a01b0382166000908152600d602052604081208054859290614a77908490615381565b90915550506001600160a01b038083166000908152600e6020908152604080832093851683529290529081208054859290614830908490615381565b6001600160a01b0382166000908152600d602052604081208054859290614adb90849061536e565b90915550506001600160a01b038083166000908152600e602090815260408083209385168352929052908120805485929061483090849061536e565b6001600160a01b038216614b6d5760405162461bcd60e51b815260206004820152601b60248201527f546f6b656e20616464726573732063616e6e6f74206265203078300000000000604482015260640161147c565b801515600103614fc4576001600160a01b038216600090815260076020526040902054614bec5760405162461bcd60e51b815260206004820152602760248201527f526577617264732070657220686f7572206d75737420626520677265617465726044820152660207468616e20360cc1b606482015260840161147c565b6001600160a01b038216600090815260066020526040902054614c635760405162461bcd60e51b815260206004820152602960248201527f436f6d706f756e64206672657175656e6379206d75737420626520677265617460448201526806572207468616e20360bc1b606482015260840161147c565b6001600160a01b038216600090815260086020526040902054614cd65760405162461bcd60e51b815260206004820152602560248201527f5769746864726177616c20666565206d75737420626520677265617465722074604482015264068616e20360dc1b606482015260840161147c565b6001600160a01b038216600090815260096020526040902054614d505760405162461bcd60e51b815260206004820152602c60248201527f466f756e646572732072657761726420626f6f7374206d75737420626520677260448201526b06561746572207468616e20360a41b606482015260840161147c565b6001600160a01b0382166000908152600a6020526040902054614dc65760405162461bcd60e51b815260206004820152602860248201527f6b4e46542072657761726420626f6f7374206d75737420626520677265617465604482015267072207468616e20360c41b606482015260840161147c565b6001600160a01b0382166000908152600b6020526040902054614e2b5760405162461bcd60e51b815260206004820152601c60248201527f526174696f206d7573742062652067726561746572207468616e203000000000604482015260640161147c565b6001600160a01b038216600090815260056020526040902054614e9c5760405162461bcd60e51b8152602060048201526024808201527f4d696e696d756d207374616b65206d75737420626520677265617465722074686044820152630616e20360e41b606482015260840161147c565b6001600160a01b038216600090815260146020526040902054614f015760405162461bcd60e51b815260206004820152601e60248201527f44697669736f72206d7573742062652067726561746572207468616e20300000604482015260640161147c565b6000826001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015614f41573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614f6591906152e0565b11614fc45760405162461bcd60e51b815260206004820152602960248201527f546f6b656e20746f74616c20737570706c79206d75737420626520677265617460448201526806572207468616e20360bc1b606482015260840161147c565b6001600160a01b038216600081815260046020526040808220805460ff191685151590811790915590519092917f59261974a183535ca20bb33ae77db42c679a079844739a2e10f0b6ecb847379a91a35050565b6001600160a01b038116811461502d57600080fd5b50565b6000806040838503121561504357600080fd5b823561504e81615018565b946020939093013593505050565b600081518084526020808501945080840160005b8381101561508c57815187529582019590820190600101615070565b509495945050505050565b6040815260006150aa604083018561505c565b82810360208401526150bc818561505c565b95945050505050565b6000602082840312156150d757600080fd5b81356150e281615018565b9392505050565b6000602082840312156150fb57600080fd5b5035919050565b6000806040838503121561511557600080fd5b82359150602083013561512781615018565b809150509250929050565b6000806040838503121561514557600080fd5b50508035926020909101359150565b60ff8116811461502d57600080fd5b60008060006060848603121561517857600080fd5b83359250602084013561518a81615154565b9150604084013561519a81615018565b809150509250925092565b600080604083850312156151b857600080fd5b82356151c381615018565b9150602083013561512781615018565b801515811461502d57600080fd5b600080604083850312156151f457600080fd5b82356151ff81615018565b91506020830135615127816151d3565b600080600080600080600080610100898b03121561522c57600080fd5b883561523781615018565b9a60208a01359a5060408a013599606081013599506080810135985060a0810135975060c0810135965060e00135945092505050565b6000806040838503121561528057600080fd5b823591506020830135615127816151d3565b6020815260006150e2602083018461505c565b600080604083850312156152b857600080fd5b82356151c381615154565b6000602082840312156152d557600080fd5b81356150e281615154565b6000602082840312156152f257600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b80820260008212600160ff1b8414161561532b5761532b6152f9565b8181058314821517611b7357611b736152f9565b634e487b7160e01b600052603260045260246000fd5b600060018201615367576153676152f9565b5060010190565b80820180821115611b7357611b736152f9565b81810381811115611b7357611b736152f9565b8082028115828204841417611b7357611b736152f9565b6000826153c857634e487b7160e01b600052601260045260246000fd5b500490565b6000602082840312156153df57600080fd5b81516150e281615018565b6000602082840312156153fc57600080fd5b81516150e2816151d3565b60ff8281168282160390811115611b7357611b736152f9565b600181815b8085111561545b578160001904821115615441576154416152f9565b8085161561544e57918102915b93841c9390800290615425565b509250929050565b60008261547257506001611b73565b8161547f57506000611b73565b8160018114615495576002811461549f576154bb565b6001915050611b73565b60ff8411156154b0576154b06152f9565b50506001821b611b73565b5060208310610133831016604e8410600b84101617156154de575081810a611b73565b6154e88383615420565b80600019048211156154fc576154fc6152f9565b029392505050565b60006150e28383615463565b60006020828403121561552257600080fd5b81516150e28161515456fe546f6b656e2061646472657373206973206e6f74207365740000000000000000a164736f6c6343000811000a546f6b656e2061646472657373206973206e6f742073657400000000000000000000000000000000000000006a005c11217863c4e300ce009c5ddc7e1672150a0000000000000000000000007ca5af5ba3472af6049f63c1abc324475d44efc1000000000000000000000000ad2e62e90c63d5c2b905c3f709cc3045aecdaa1e0000000000000000000000000fd5576c2842bd62dd00c5256491d11ccad84306000000000000000000000000ea6ab2871d5b3bbe6ded740c812d85700bae33c000000000000000000000000069a4a1cd8f2f2c3500f64634b9d69c642e9a5ca4
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106105a15760003560e01c806384d3d586116102ed578063d55111c511610191578063f0d33cad116100ee578063f384fe76116100a2578063fb68d53b1161007c578063fb68d53b14610f99578063fe1686b814610fd3578063fe31b2281461100d57600080fd5b8063f384fe7614610f30578063f91159e314610f50578063fad68d1f14610f7957600080fd5b8063f16b41f4116100d3578063f16b41f414610e2a578063f19d684914610ef4578063f2760e9d14610f0757600080fd5b8063f0d33cad14610deb578063f0f4426014610e1757600080fd5b8063e519cf1711610145578063ec6401531161012a578063ec64015314610da2578063f02842a514610db5578063f02d4a4514610dd857600080fd5b8063e519cf1714610d59578063ea425a6d14610d8257600080fd5b8063dad775b111610176578063dad775b114610d0a578063dd2a8b1114610d1d578063e37d47e414610d4657600080fd5b8063d55111c514610cd7578063d6b9243414610cea57600080fd5b8063b54b9c881161024a578063bf811fbc116101fe578063c706fee5116101d8578063c706fee514610c88578063cf717c8c14610cb1578063cfb656a514610cc457600080fd5b8063bf811fbc14610c2c578063c39ccf8814610c3f578063c5ebc2f714610c6857600080fd5b8063ba5771481161022f578063ba57714814610bf3578063beb8314c14610c06578063bf7e214f14610c1957600080fd5b8063b54b9c8814610bb0578063b6740c3b14610bd057600080fd5b80639bfd8d61116102a1578063a55dfa1c11610286578063a55dfa1c14610b77578063a9b2940714610b8a578063aaa78db414610b9d57600080fd5b80639bfd8d6114610b44578063a13d507914610b6457600080fd5b806389d5e38a116102d257806389d5e38a14610b0b578063911ddf0a14610b1e57806396ce362714610b3157600080fd5b806384d3d58614610ad857806387eebaea14610af857600080fd5b80634715f40c116104545780635a5392be116103b157806372aa9d91116103655780637b16c5431161033f5780637b16c54314610a7a5780637bf7f3d314610aa55780637cbfd14414610ab857600080fd5b806372aa9d9114610a3457806378e2816b14610a545780637a9e5e4b14610a6757600080fd5b80635dfa4596116103965780635dfa4596146109d657806361d027b314610a015780636e3c115414610a1457600080fd5b80635a5392be146109a05780635cd3667e146109c357600080fd5b80635385689c116104085780635722dee0116103ed5780635722dee014610931578063580e26a11461095a57806359b0e5901461097d57600080fd5b80635385689c146108e6578063546f2b661461091157600080fd5b80634a912ce5116104395780634a912ce5146108785780634e781513146108ab5780635328c2bf146108be57600080fd5b80634715f40c1461083c5780634774dc931461086557600080fd5b80632bcf161c116105025780633d0132e7116104b6578063404d221a1161049b578063404d221a14610803578063441a3e70146108165780634477c9741461082957600080fd5b80633d0132e7146107a85780633dc60a70146107f057600080fd5b806338c26d18116104e757806338c26d181461072d5780633a46a46d146107655780633ae5713d1461078557600080fd5b80632bcf161c146106f1578063336cada81461071a57600080fd5b8063171f9ce4116105595780631c5122d91161053e5780631c5122d9146106955780631e78e9a2146106be5780631f6514db146106de57600080fd5b8063171f9ce41461065f57806319720be11461067257600080fd5b80630962ef791161058a5780630962ef79146105fe57806310b1843814610613578063151a63491461063657600080fd5b80630399be55146105a657806306811c92146105d0575b600080fd5b6105b96105b4366004615030565b61102d565b6040516105c7929190615097565b60405180910390f35b6105f06105de3660046150c5565b60076020526000908152604090205481565b6040519081526020016105c7565b61061161060c3660046150e9565b611409565b005b6105f06106213660046150e9565b60009081526003602052604090206007015490565b6105f06106443660046150c5565b6001600160a01b031660009081526011602052604090205490565b61061161066d366004615102565b611765565b6105f06106803660046150e9565b60009081526003602052604090206005015490565b6105f06106a33660046150c5565b6001600160a01b031660009081526007602052604090205490565b6105f06106cc3660046150c5565b600a6020526000908152604090205481565b6106116106ec366004615102565b6117f7565b6105f06106ff3660046150c5565b6001600160a01b03166000908152600f602052604090205490565b610611610728366004615102565b611889565b61075361073b3660046150e9565b60009081526003602052604090206008015460ff1690565b60405160ff90911681526020016105c7565b6105f06107733660046150c5565b600b6020526000908152604090205481565b6107536107933660046150c5565b600c6020526000908152604090205460ff1681565b6107bb6107b6366004615030565b61191b565b60408051968752602087019590955260ff909316938501939093526060840152608083019190915260a082015260c0016105c7565b6105f06107fe366004615030565b611984565b610611610811366004615102565b611b79565b610611610824366004615132565b611c0b565b6106116108373660046150e9565b61236d565b6105f061084a3660046150c5565b6001600160a01b031660009081526009602052604090205490565b6105f0610873366004615163565b6125ec565b61089b6108863660046150e9565b60156020526000908152604090205460ff1681565b60405190151581526020016105c7565b6106116108b9366004615132565b612ca6565b6108d16108cc3660046150e9565b6134c9565b604080519283526020830191909152016105c7565b6019546108f9906001600160a01b031681565b6040516001600160a01b0390911681526020016105c7565b6105f061091f3660046150c5565b60096020526000908152604090205481565b6105f061093f3660046150c5565b6001600160a01b031660009081526008602052604090205490565b61089b6109683660046150c5565b60046020526000908152604090205460ff1681565b6105f061098b3660046150e9565b60009081526003602052604090206004015490565b6105f06109ae3660046150e9565b60009081526003602052604090206002015490565b6106116109d1366004615132565b613500565b6105f06109e43660046151a5565b600e60209081526000928352604080842090915290825290205481565b601a546108f9906001600160a01b031681565b6105f0610a223660046150e9565b60009081526013602052604090205490565b6105f0610a423660046150c5565b60056020526000908152604090205481565b610611610a623660046150c5565b61351a565b610611610a753660046150c5565b6135c2565b6105f0610a883660046151a5565b601060209081526000928352604080842090915290825290205481565b610611610ab33660046151e1565b61361e565b6105f0610ac63660046150c5565b60116020526000908152604090205481565b6105f0610ae63660046150c5565b60126020526000908152604090205481565b610611610b06366004615132565b613678565b6105f0610b193660046150c5565b61368b565b610611610b2c36600461520f565b6136e6565b610611610b3f366004615030565b613b6b565b6105f0610b523660046150c5565b600d6020526000908152604090205481565b610611610b72366004615102565b613c4a565b6105f0610b853660046150e9565b613cdc565b6017546108f9906001600160a01b031681565b610611610bab36600461526d565b613d3e565b6105f0610bbe3660046150c5565b60086020526000908152604090205481565b6105f0610bde3660046150e9565b60009081526003602052604090206009015490565b6105f0610c01366004615030565b613d66565b6105f0610c14366004615030565b613d97565b6000546108f9906001600160a01b031681565b610611610c3a3660046150c5565b613f02565b6105f0610c4d3660046150c5565b6001600160a01b031660009081526005602052604090205490565b610c7b610c763660046150c5565b613faa565b6040516105c79190615292565b6105f0610c963660046150c5565b6001600160a01b03166000908152600b602052604090205490565b610611610cbf366004615102565b614016565b610611610cd23660046150c5565b614136565b6018546108f9906001600160a01b031681565b6105f0610cf83660046150c5565b60146020526000908152604090205481565b610611610d18366004615102565b6141de565b6105f0610d2b3660046150c5565b6001600160a01b03166000908152600d602052604090205490565b610611610d54366004615102565b614270565b6105f0610d673660046150c5565b6001600160a01b03166000908152600a602052604090205490565b6105f0610d903660046150c5565b60066020526000908152604090205481565b6105f0610db0366004615030565b614302565b61089b610dc33660046150e9565b60009081526015602052604090205460ff1690565b6105b9610de63660046150c5565b61435f565b610753610df93660046150c5565b6001600160a01b03166000908152600c602052604090205460ff1690565b610611610e253660046150c5565b6146ad565b610e9c610e383660046150e9565b600360208190526000918252604090912080546001820154600283015493830154600484015460058501546006860154600787015460088801546009909801546001600160a01b0397881699969097169795969495939492939192909160ff16908a565b604080516001600160a01b039b8c1681529a90991660208b0152978901969096526060880194909452608087019290925260a086015260c085015260e084015260ff16610100830152610120820152610140016105c7565b610611610f023660046152a5565b614755565b6105f0610f153660046150c5565b6001600160a01b031660009081526012602052604090205490565b6105f0610f3e3660046150c5565b600f6020526000908152604090205481565b6105f0610f5e3660046150c5565b6001600160a01b031660009081526014602052604090205490565b6105f0610f873660046150e9565b60136020526000908152604090205481565b6105f0610fa73660046151a5565b6001600160a01b0380821660009081526010602090815260408083209386168352929052205492915050565b6105f0610fe13660046151a5565b6001600160a01b038082166000908152600e602090815260408083209386168352929052205492915050565b6105f061101b3660046152c3565b60166020526000908152604090205481565b6019546040516370a0823160e01b81526001600160a01b0384811660048301526060928392600092909116906370a0823190602401602060405180830381865afa15801561107f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110a391906152e0565b60408051600580825260c082019092529192506020820160a080368337505060408051600580825260c0820190925292955090506020820160a08036833701905050915060005b8181101561140057601954604051632f745c5960e01b81526001600160a01b038881166004830152602482018490526000921690632f745c5990604401602060405180830381865afa158015611144573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061116891906152e0565b600087815260036020526040908190206005015460195491516319d42f2f60e21b815260048101849052929350916001600160a01b0390911690636750bcbc90602401602060405180830381865afa1580156111c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111ec91906152e0565b11156111f857506113ee565b60195460405163032bbfbd60e21b81526004810183905260006024820181905260016044830152916001600160a01b031690630caefef490606401602060405180830381865afa158015611250573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061127491906152e0565b60008181526015602052604090205490915060ff166112945750506113ee565b60195460405163032bbfbd60e21b81526004810184905260016024820152600260448201526000916001600160a01b031690630caefef490606401602060405180830381865afa1580156112ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061131091906152e0565b61131b90606461530f565b9050600081121561132a575060005b60005b60058110156113e9578781815181106113485761134861533f565b60200260200101518211156113d757600088828151811061136b5761136b61533f565b60200260200101519050828983815181106113885761138861533f565b60200260200101818152505080925060008883815181106113ab576113ab61533f565b60200260200101519050858984815181106113c8576113c861533f565b60209081029190910101529450505b806113e181615355565b91505061132d565b505050505b806113f881615355565b9150506110ea565b50509250929050565b6000818152600360205260409020600101546001600160a01b031633146114855760405162461bcd60e51b815260206004820152602560248201527f596f7520617265206e6f7420746865206f776e6572206f6620746869732064656044820152641c1bdcda5d60da1b60648201526084015b60405180910390fd5b6000818152600360205260409020600701544210156114e65760405162461bcd60e51b815260206004820152601360248201527f54696d656c6f636b206e6f742070617373656400000000000000000000000000604482015260640161147c565b6000818152600360205260408120600601546115023384613d97565b61150c919061536e565b90506000811161155e5760405162461bcd60e51b815260206004820152601360248201527f596f752068617665206e6f207265776172647300000000000000000000000000604482015260640161147c565b600082815260036020908152604080832060068101849055426004820155546001600160a01b03168084526014835281842054600890935290832054909291906115aa90612710615381565b6115b49085615394565b6115be91906153ab565b905060006115cc8285615381565b9050826001600160a01b03166323b872dd60008054906101000a90046001600160a01b03166001600160a01b031663fbfa77cf6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561162e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061165291906153cd565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152336024820152604481018590526064016020604051808303816000875af11580156116a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116c991906153ea565b50600085815260036020526040902080546001909101546116f89184916001600160a01b0391821691166147cc565b6117226117058386615381565b6000878152600360205260409020546001600160a01b031661483a565b604080518381526020810183905233917f02a6a2be713fedf52f113c0a759f1c1a23a113476d9b1b1a2a453c910660de4e91015b60405180910390a25050505050565b61176d61486b565b6001600160a01b0381166117b15760405162461bcd60e51b8152602060048201526018602482015260008051602061552e833981519152604482015260640161147c565b6001600160a01b0381166000818152600b60205260408082208590555184917f62b574cc62ed3db0ae736cb4349346a234832cc8b215c6423fd67505addc2ffa91a35050565b6117ff61486b565b6001600160a01b0381166118435760405162461bcd60e51b8152602060048201526018602482015260008051602061552e833981519152604482015260640161147c565b6001600160a01b0381166000818152600960205260408082208590555184917f1677c34b69a09796446af7a4c75943a1bb36202c16eb82199ef7d37d0ee4b28891a35050565b61189161486b565b6001600160a01b0381166118d55760405162461bcd60e51b8152602060048201526018602482015260008051602061552e833981519152604482015260640161147c565b6001600160a01b0381166000818152600760205260408082208590555184917fef97689adaec5b60041d413c3baef6876d5d01bb6c17b60cc980e2e244ef851791a35050565b60008060008060008061193d8760009081526003602052604090206007015490565b60008881526003602052604090206005810154600890910154919750955060ff169350611969876134c9565b90935091506119788888611984565b90509295509295509295565b600081815260036020818152604080842081516101408101835281546001600160a01b0390811680835260018401548216838701526002840154838601529583015460608301526004808401546080840152600584015460a0840152600684015460c0840152600784015460e0840152600884015460ff1661010084015260099093015461012083015294865260149093528185205460185492516370a0823160e01b81528886169281019290925294929391909116906370a0823190602401602060405180830381865afa158015611a61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a8591906152e0565b1115611ab25780516001600160a01b0316600090815260096020526040902054611aaf908361536e565b91505b6019546040516370a0823160e01b81526001600160a01b03868116600483015260009216906370a0823190602401602060405180830381865afa158015611afd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b2191906152e0565b1115611b3e57611b318484614302565b611b3b908361536e565b91505b61010081015160ff1615611b715761010081015160ff16600090815260136020526040902054611b6e908361536e565b91505b505b92915050565b611b8161486b565b6001600160a01b038116611bc55760405162461bcd60e51b8152602060048201526018602482015260008051602061552e833981519152604482015260640161147c565b6001600160a01b0381166000818152600560205260408082208590555184917fef3cb734d88702dbb1c3bc381c52176876be95e70b66d3970d16653ee992a6c291a35050565b600081815260036020526040902060070154421015611c6c5760405162461bcd60e51b815260206004820152601360248201527f54696d656c6f636b206e6f742070617373656400000000000000000000000000604482015260640161147c565b6000818152600360205260409020600101546001600160a01b03163314611ce35760405162461bcd60e51b815260206004820152602560248201527f596f7520617265206e6f7420746865206f776e6572206f6620746869732064656044820152641c1bdcda5d60da1b606482015260840161147c565b600081815260036020526040902060020154821115611d4e5760405162461bcd60e51b815260206004820152602160248201527f43616e2774207769746864726177206d6f7265207468616e20796f75206861766044820152606560f81b606482015260840161147c565b6017546040516370a0823160e01b81523360048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015611d96573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dba91906152e0565b600082815260036020526040902060090154611dd69084615394565b1115611e4a5760405162461bcd60e51b815260206004820152603760248201527f43616e2774207769746864726177206d6f726520746f6b656e73207468616e2060448201527f74686520636f6c6c61746572616c20796f752068617665000000000000000000606482015260840161147c565b6000611e563383613d97565b905082600360008481526020019081526020016000206002016000828254611e7e9190615381565b909155505060008281526003602052604081204260048201556006018054839290611eaa90849061536e565b90915550506000828152600360209081526040808320546001600160a01b031683526014808352818420546008845291842054925290611eea9082615381565b611ef49086615394565b611efe91906153ab565b90506000611f0c8286615381565b6000858152600360209081526040808320549254815163fbfa77cf60e01b815291519495506001600160a01b03938416948794869463dd62ed3e94919093169263fbfa77cf926004808401938290030181865afa158015611f71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f9591906153cd565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152306024820152604401602060405180830381865afa158015611fdf573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061200391906152e0565b10156120a85760405162461bcd60e51b815260206004820152606260248201527f547265617375727920436f6e7472616374206e65656420746f20617070726f7660448201527f65205374616b696e6720436f6e747261637420746f207769746864726177207960648201527f6f757220746f6b656e73202d2d20706c656173652063616c6c20616e2041646d60848201526134b760f11b60a482015260c40161147c565b600085815260036020526040902080546001909101546120d69188916001600160a01b039182169116614942565b6000858152600360209081526040808320546001600160a01b039081168452600c90925280832054601754909216835282205460ff918216929116908183101561212e576121248383615407565b60ff169050612132565b5060005b6017546001600160a01b0316639dc29fac3361214f84600a615504565b60008c81526003602052604090206009015461216b908e615394565b6121759190615394565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b1580156121bb57600080fd5b505af11580156121cf573d6000803e3d6000fd5b50505050836001600160a01b03166323b872dd60008054906101000a90046001600160a01b03166001600160a01b031663fbfa77cf6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612233573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061225791906153cd565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152336024820152604481018990526064016020604051808303816000875af11580156122aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122ce91906153ea565b50600088815260036020526040902080546001909101546122fd9188916001600160a01b0391821691166147cc565b61232761230a878b615381565b60008a8152600360205260409020546001600160a01b031661483a565b604080518781526020810187905233917ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b568910160405180910390a2505050505050505050565b6000818152600360205260409020600101546001600160a01b031633146123e45760405162461bcd60e51b815260206004820152602560248201527f596f7520617265206e6f7420746865206f776e6572206f6620746869732064656044820152641c1bdcda5d60da1b606482015260840161147c565b6000818152600360205260408120600601546124003384613d97565b61240a919061536e565b90506000811161245c5760405162461bcd60e51b815260206004820152601460248201527f4e6f207265776172647320617661696c61626c65000000000000000000000000604482015260640161147c565b600082815260036020526040812060068101829055600201805483929061248490849061536e565b9091555050600082815260036020526040902042600482015580546001909101546124bd9183916001600160a01b039182169116614ab3565b6000828152600360209081526040808320546001600160a01b039081168452600c90925280832054601754909216835282205460ff91821692911690828211156125155761250b8383615407565b60ff169050612519565b5060005b6017546001600160a01b03166340c10f193361253684600a615504565b6000898152600360205260409020600901546125529089615394565b61255c9190615394565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b1580156125a257600080fd5b505af11580156125b6573d6000803e3d6000fd5b50506040518681523392507f169f1815ebdea059aac3bb00ec9a9594c7a5ffcb64a17e8392b5d84909a145569150602001611756565b60006001600160a01b0382166126325760405162461bcd60e51b8152602060048201526018602482015260008051602061552e833981519152604482015260640161147c565b6001600160a01b03821660009081526004602052604090205460ff1661269a5760405162461bcd60e51b815260206004820152601460248201527f546f6b656e206e6f7420617574686f72697a6564000000000000000000000000604482015260640161147c565b6001600160a01b0382166000908152600560205260409020548410156127105760405162461bcd60e51b815260206004820152602560248201527f416d6f756e7420736d616c6c6572207468616e206d696e696d696d756d2064656044820152641c1bdcda5d60da1b606482015260840161147c565b6040516370a0823160e01b8152336004820152829085906001600160a01b038316906370a0823190602401602060405180830381865afa158015612758573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061277c91906152e0565b10156127ca5760405162461bcd60e51b815260206004820152601d60248201527f43616e2774207374616b65206d6f7265207468616e20796f75206f776e000000604482015260640161147c565b604051636eb1769f60e11b815233600482015230602482015285906001600160a01b0383169063dd62ed3e90604401602060405180830381865afa158015612816573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061283a91906152e0565b10156128885760405162461bcd60e51b815260206004820152601160248201527f416c6c6f77616e6365206e6f7420736574000000000000000000000000000000604482015260640161147c565b60038460ff1611156128dc5760405162461bcd60e51b815260206004820152601060248201527f496e76616c69642074696d656c6f636b00000000000000000000000000000000604482015260640161147c565b60006128e760015490565b9050604051806101400160405280856001600160a01b03168152602001336001600160a01b031681526020018781526020016000815260200142815260200142815260200160008152602001601660008860ff1660ff1681526020019081526020016000205442612958919061536e565b815260ff8781166020808401919091526001600160a01b038881166000908152600b8352604080822054958101959095528681526003808452858220875181546001600160a01b0319908116918616919091178255888601516001808401805490931691909616179055878701516002808301919091556060890151928201929092556080880151600482015560a0880151600582015560c0880151600682015560e0880151600782015561010088015160088201805460ff191691909716179095556101209096015160099094019390935533808452948252928220805493840181558252902001829055612a519087908690614ab3565b6001600160a01b038085166000908152600c602052604080822054601754909316825281205460ff92831692169082821115612a9b57612a918383615407565b60ff169050612a9f565b5060005b846001600160a01b03166323b872dd3360008054906101000a90046001600160a01b03166001600160a01b031663fbfa77cf6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612b00573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b2491906153cd565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604481018c90526064016020604051808303816000875af1158015612b78573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b9c91906153ea565b506017546001600160a01b03166340c10f1933612bba84600a615504565b6001600160a01b038b166000908152600b6020526040902054612bdd908e615394565b612be79190615394565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015612c2d57600080fd5b505af1158015612c41573d6000803e3d6000fd5b50505050612c53600180546001019055565b604080516001600160a01b0389168152602081018b9052339186917ff7373f56c201647feae85a62d3cf56286ed3a43d20c5eb7f9883d6ea690ef7c0910160405180910390a35091979650505050505050565b6000818152600360205260409020600101546001600160a01b03163314612d1d5760405162461bcd60e51b815260206004820152602560248201527f596f7520617265206e6f7420746865206f776e6572206f6620746869732064656044820152641c1bdcda5d60da1b606482015260840161147c565b600081815260036020526040902060020154821115612d885760405162461bcd60e51b815260206004820152602160248201527f43616e2774207769746864726177206d6f7265207468616e20796f75206861766044820152606560f81b606482015260840161147c565b6017546040516370a0823160e01b81523360048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015612dd0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612df491906152e0565b600082815260036020526040902060090154612e109084615394565b1115612e845760405162461bcd60e51b815260206004820152603760248201527f43616e2774207769746864726177206d6f726520746f6b656e73207468616e2060448201527f74686520636f6c6c61746572616c20796f752068617665000000000000000000606482015260840161147c565b6000818152600360205260409020600701544210612ee45760405162461bcd60e51b815260206004820152601360248201527f54696d656c6f636b206861732070617373656400000000000000000000000000604482015260640161147c565b600081815260036020526040812060070154612f01904290615381565b600083815260036020526040812060058101546007909101549293509091612f299190615381565b90506000612f38826064615394565b6000858152600360209081526040808320546001600160a01b0316835260129091529020548490612f699088615394565b612f739190615394565b612f7d91906153ab565b905084811115612f8a5750835b80600003612fac576064612f9f866001615394565b612fa991906153ab565b90505b6000848152600360209081526040808320546001600160a01b031683526008909152812054612fdb908361536e565b90506000612fe98288615381565b90506000612ff78289615381565b90508760036000898152602001908152602001600020600201600082825461301f9190615381565b909155505060008781526003602090815260408083204260048083019190915590549354825163fbfa77cf60e01b815292516001600160a01b03958616958895879563dd62ed3e95929094169363fbfa77cf938184019390918290030181865afa158015613091573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130b591906153cd565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152306024820152604401602060405180830381865afa1580156130ff573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061312391906152e0565b10156131c85760405162461bcd60e51b815260206004820152606260248201527f547265617375727920436f6e7472616374206e65656420746f20617070726f7660448201527f65205374616b696e6720436f6e747261637420746f207769746864726177207960648201527f6f757220746f6b656e73202d2d20706c656173652063616c6c20616e2041646d60848201526134b760f11b60a482015260c40161147c565b600088815260036020526040902080546001909101546131f6918b916001600160a01b039182169116614942565b6017546001600160a01b039081166000908152600c60208181526040808420548d855260038352818520549095168452919052812054909160ff90811691161015613289576000898152600360209081526040808320546001600160a01b039081168452600c9092528083205460175490921683529091205461327f9160ff9081169116615407565b60ff16905061328d565b5060005b6017546001600160a01b0316639dc29fac336132aa84600a615504565b60008d8152600360205260409020600901546132c6908f615394565b6132d09190615394565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b15801561331657600080fd5b505af115801561332a573d6000803e3d6000fd5b50505050816001600160a01b03166323b872dd60008054906101000a90046001600160a01b03166001600160a01b031663fbfa77cf6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561338e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133b291906153cd565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152336024820152604481018790526064016020604051808303816000875af1158015613405573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061342991906153ea565b50600089815260036020526040902080546001909101546134589186916001600160a01b0391821691166147cc565b613482613465858c615381565b60008b8152600360205260409020546001600160a01b031661483a565b604080518581526020810185905233917ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b568910160405180910390a250505050505050505050565b600081815260036020526040812060028101546006909101549091906134ef3385613d97565b6134f9919061536e565b9050915091565b61350861486b565b60009182526013602052604090912055565b61352261486b565b6001600160a01b0381166135785760405162461bcd60e51b815260206004820152601e60248201527f466f756e6465727320616464726573732063616e6e6f74206265203078300000604482015260640161147c565b601880546001600160a01b0319166001600160a01b0383169081179091556040517f23008753c65029d55e051a14341d50cf19b808653ba432a5faeb07bd7865e25b90600090a250565b6135ca61486b565b600080546001600160a01b0319166001600160a01b0383169081179091556040519081527f2f658b440c35314f52658ea8a740e05b284cdc84dc9ae01e891f21b8933e7cad9060200160405180910390a150565b61362661486b565b6001600160a01b03821661366a5760405162461bcd60e51b8152602060048201526018602482015260008051602061552e833981519152604482015260640161147c565b6136748282614b17565b5050565b6136828282611c0b565b61367481611409565b6000806136978361435f565b50905060005b60058110156136df578181815181106136b8576136b861533f565b6020026020010151836136cb919061536e565b9250806136d781615355565b91505061369d565b5050919050565b6136ee61486b565b6001600160a01b0388166137445760405162461bcd60e51b815260206004820152601b60248201527f546f6b656e20616464726573732063616e6e6f74206265203078300000000000604482015260640161147c565b600087116137a45760405162461bcd60e51b815260206004820152602760248201527f526577617264732070657220686f7572206d75737420626520677265617465726044820152660207468616e20360cc1b606482015260840161147c565b600086116138065760405162461bcd60e51b815260206004820152602960248201527f436f6d706f756e64206672657175656e6379206d75737420626520677265617460448201526806572207468616e20360bc1b606482015260840161147c565b600085116138645760405162461bcd60e51b815260206004820152602560248201527f5769746864726177616c20666565206d75737420626520677265617465722074604482015264068616e20360dc1b606482015260840161147c565b600084116138c95760405162461bcd60e51b815260206004820152602c60248201527f466f756e646572732072657761726420626f6f7374206d75737420626520677260448201526b06561746572207468616e20360a41b606482015260840161147c565b6000831161392a5760405162461bcd60e51b815260206004820152602860248201527f6b4e46542072657761726420626f6f7374206d75737420626520677265617465604482015267072207468616e20360c41b606482015260840161147c565b6000821161397a5760405162461bcd60e51b815260206004820152601c60248201527f526174696f206d7573742062652067726561746572207468616e203000000000604482015260640161147c565b600081116139d65760405162461bcd60e51b8152602060048201526024808201527f4d696e696d756d207374616b65206d75737420626520677265617465722074686044820152630616e20360e41b606482015260840161147c565b6000886001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613a16573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a3a91906152e0565b11613a995760405162461bcd60e51b815260206004820152602960248201527f546f6b656e20746f74616c20737570706c79206d75737420626520677265617460448201526806572207468616e20360bc1b606482015260840161147c565b613aa5612710896141de565b613aaf84896117f7565b613ab98389613c4a565b613ac38789611889565b613acd8289611765565b613ad78589614016565b613ae18689614270565b613aeb8189611b79565b613b56886001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015613b2c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b509190615510565b89614755565b613b61886001614b17565b5050505050505050565b613b7361486b565b6001600160a01b038216613bb75760405162461bcd60e51b8152602060048201526018602482015260008051602061552e833981519152604482015260640161147c565b6064811115613c2e5760405162461bcd60e51b815260206004820152602c60248201527f50656e616c74792070657263656e74616765206d75737420626520626574776560448201527f656e203020616e64203130300000000000000000000000000000000000000000606482015260840161147c565b6001600160a01b03909116600090815260126020526040902055565b613c5261486b565b6001600160a01b038116613c965760405162461bcd60e51b8152602060048201526018602482015260008051602061552e833981519152604482015260640161147c565b6001600160a01b0381166000818152600a60205260408082208590555184917f11ef1060a695a1277b08edcbb2c364d43d4eb52f1060daaabf0df445cb6cdfdf91a35050565b6000818152600360209081526040808320600481015490546001600160a01b031684526006909252822054613d11818361536e565b4210613d21575060009392505050565b42613d2c828461536e565b613d369190615381565b949350505050565b613d4661486b565b600091825260156020526040909120805460ff1916911515919091179055565b60026020528160005260406000208181548110613d8257600080fd5b90600052602060002001600091509150505481565b600081815260036020818152604080842081516101408101835281546001600160a01b0390811682526001830154811694820185905260028301549382019390935293810154606085015260048101546080850152600581015460a0850152600681015460c0850152600781015460e0850152600881015460ff1661010085015260090154610120840152851614613e33576000915050611b73565b6000816080015142613e459190615381565b60408084015184516001600160a01b03166000908152600760205291822054929350919063bbf81e00613e788385615394565b613e8a90670de0b6b3a7640000615394565b613e9491906153ab565b90506000670de0b6b3a7640000613eab8387615394565b613eb591906153ab565b90506000613ec38a8a611984565b87516001600160a01b0316600090815260146020526040902054909150613eea8284615394565b613ef491906153ab565b9a9950505050505050505050565b613f0a61486b565b6001600160a01b038116613f605760405162461bcd60e51b815260206004820152601a60248201527f6b4e465420616464726573732063616e6e6f7420626520307830000000000000604482015260640161147c565b601980546001600160a01b0319166001600160a01b0383169081179091556040517fc8e08c5b2fa487609cdc92d5cfcc240f3c8fc73ac5e58fafc5d465d20aaaf31290600090a250565b6001600160a01b03811660009081526002602090815260409182902080548351818402810184019094528084526060939283018282801561400a57602002820191906000526020600020905b815481526020019060010190808311613ff6575b50505050509050919050565b61401e61486b565b6001600160a01b0381166140625760405162461bcd60e51b8152602060048201526018602482015260008051602061552e833981519152604482015260640161147c565b6001600160a01b0381166000908152601460205260409020548211156140f05760405162461bcd60e51b815260206004820152602760248201527f5769746864726177616c206665652063616e6e6f74206265206d6f726520746860448201527f616e203130302500000000000000000000000000000000000000000000000000606482015260840161147c565b6001600160a01b0381166000818152600860205260408082208590555184917f5d5169bb1fbf418e612b1934f181b6ce300a1aad27fdb0e6f6aadbd96f50bb8f91a35050565b61413e61486b565b6001600160a01b0381166141945760405162461bcd60e51b815260206004820152601b60248201527f48656c697820616464726573732063616e6e6f74206265203078300000000000604482015260640161147c565b601780546001600160a01b0319166001600160a01b0383169081179091556040517fdcbeffeaf77a19486e34d4b5fc3809913d1e7125a43b8dcdb17944ab2c17579090600090a250565b6141e661486b565b6001600160a01b03811661422a5760405162461bcd60e51b8152602060048201526018602482015260008051602061552e833981519152604482015260640161147c565b6001600160a01b0381166000818152601460205260408082208590555184917f6a437d814668577dce2f82ae56ed67161e12e20b59b9464687859d6a2ce0faa591a35050565b61427861486b565b6001600160a01b0381166142bc5760405162461bcd60e51b8152602060048201526018602482015260008051602061552e833981519152604482015260640161147c565b6001600160a01b0381166000818152600660205260408082208590555184917fd0d3d840363c3a773f4578f92d7914f6b37985570c79ee2889d69d7d8f12c29591a35050565b60008061430f848461102d565b50905060005b6005811015614357578181815181106143305761433061533f565b602002602001015183614343919061536e565b92508061434f81615355565b915050614315565b505092915050565b6019546040516370a0823160e01b81526001600160a01b0383811660048301526060928392600092909116906370a0823190602401602060405180830381865afa1580156143b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906143d591906152e0565b60408051600580825260c082019092529192506020820160a080368337505060408051600580825260c0820190925292955090506020820160a08036833701905050915060005b818110156146a657601954604051632f745c5960e01b81526001600160a01b038781166004830152602482018490526000921690632f745c5990604401602060405180830381865afa158015614476573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061449a91906152e0565b60195460405163032bbfbd60e21b815260048101839052600060248201819052600160448301529293506001600160a01b0390911690630caefef490606401602060405180830381865afa1580156144f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061451a91906152e0565b60008181526015602052604090205490915060ff1661453a575050614694565b60195460405163032bbfbd60e21b81526004810184905260016024820152600260448201526000916001600160a01b031690630caefef490606401602060405180830381865afa158015614592573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906145b691906152e0565b6145c190606461530f565b905060008112156145d0575060005b60005b600581101561468f578781815181106145ee576145ee61533f565b602002602001015182111561467d5760008882815181106146115761461161533f565b602002602001015190508289838151811061462e5761462e61533f565b60200260200101818152505080925060008883815181106146515761465161533f565b602002602001015190508589848151811061466e5761466e61533f565b60209081029190910101529450505b8061468781615355565b9150506145d3565b505050505b8061469e81615355565b91505061441c565b5050915091565b6146b561486b565b6001600160a01b03811661470b5760405162461bcd60e51b815260206004820152601e60248201527f547265617375727920616464726573732063616e6e6f74206265203078300000604482015260640161147c565b601a80546001600160a01b0319166001600160a01b0383169081179091556040517fafa147634b29e2c7bd53ce194256b9f41cfb9ba3036f2b822fdd1d965beea08690600090a250565b61475d61486b565b6001600160a01b0381166147a15760405162461bcd60e51b8152602060048201526018602482015260008051602061552e833981519152604482015260640161147c565b6001600160a01b03166000908152600c60205260409020805460ff191660ff92909216919091179055565b6001600160a01b0382166000908152600f6020526040812080548592906147f490849061536e565b90915550506001600160a01b0380831660009081526010602090815260408083209385168352929052908120805485929061483090849061536e565b9091555050505050565b6001600160a01b0381166000908152601160205260408120805484929061486290849061536e565b90915550505050565b60008054906101000a90046001600160a01b03166001600160a01b0316630c340a246040518163ffffffff1660e01b8152600401602060405180830381865afa1580156148bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906148e091906153cd565b6001600160a01b0316336001600160a01b0316146149405760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a45440000000000000000000000000000000000000000604482015260640161147c565b565b6001600160a01b0382166000908152600d60205260409020548311156149d05760405162461bcd60e51b815260206004820152602560248201527f5374616b696e673a204e6f7420656e6f756768207374616b65642028436f6e7460448201527f7261637429000000000000000000000000000000000000000000000000000000606482015260840161147c565b6001600160a01b038083166000908152600e6020908152604080832093851683529290522054831115614a4f5760405162461bcd60e51b815260206004820152602160248201527f5374616b696e673a204e6f7420656e6f756768207374616b65642028557365726044820152602960f81b606482015260840161147c565b6001600160a01b0382166000908152600d602052604081208054859290614a77908490615381565b90915550506001600160a01b038083166000908152600e6020908152604080832093851683529290529081208054859290614830908490615381565b6001600160a01b0382166000908152600d602052604081208054859290614adb90849061536e565b90915550506001600160a01b038083166000908152600e602090815260408083209385168352929052908120805485929061483090849061536e565b6001600160a01b038216614b6d5760405162461bcd60e51b815260206004820152601b60248201527f546f6b656e20616464726573732063616e6e6f74206265203078300000000000604482015260640161147c565b801515600103614fc4576001600160a01b038216600090815260076020526040902054614bec5760405162461bcd60e51b815260206004820152602760248201527f526577617264732070657220686f7572206d75737420626520677265617465726044820152660207468616e20360cc1b606482015260840161147c565b6001600160a01b038216600090815260066020526040902054614c635760405162461bcd60e51b815260206004820152602960248201527f436f6d706f756e64206672657175656e6379206d75737420626520677265617460448201526806572207468616e20360bc1b606482015260840161147c565b6001600160a01b038216600090815260086020526040902054614cd65760405162461bcd60e51b815260206004820152602560248201527f5769746864726177616c20666565206d75737420626520677265617465722074604482015264068616e20360dc1b606482015260840161147c565b6001600160a01b038216600090815260096020526040902054614d505760405162461bcd60e51b815260206004820152602c60248201527f466f756e646572732072657761726420626f6f7374206d75737420626520677260448201526b06561746572207468616e20360a41b606482015260840161147c565b6001600160a01b0382166000908152600a6020526040902054614dc65760405162461bcd60e51b815260206004820152602860248201527f6b4e46542072657761726420626f6f7374206d75737420626520677265617465604482015267072207468616e20360c41b606482015260840161147c565b6001600160a01b0382166000908152600b6020526040902054614e2b5760405162461bcd60e51b815260206004820152601c60248201527f526174696f206d7573742062652067726561746572207468616e203000000000604482015260640161147c565b6001600160a01b038216600090815260056020526040902054614e9c5760405162461bcd60e51b8152602060048201526024808201527f4d696e696d756d207374616b65206d75737420626520677265617465722074686044820152630616e20360e41b606482015260840161147c565b6001600160a01b038216600090815260146020526040902054614f015760405162461bcd60e51b815260206004820152601e60248201527f44697669736f72206d7573742062652067726561746572207468616e20300000604482015260640161147c565b6000826001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015614f41573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614f6591906152e0565b11614fc45760405162461bcd60e51b815260206004820152602960248201527f546f6b656e20746f74616c20737570706c79206d75737420626520677265617460448201526806572207468616e20360bc1b606482015260840161147c565b6001600160a01b038216600081815260046020526040808220805460ff191685151590811790915590519092917f59261974a183535ca20bb33ae77db42c679a079844739a2e10f0b6ecb847379a91a35050565b6001600160a01b038116811461502d57600080fd5b50565b6000806040838503121561504357600080fd5b823561504e81615018565b946020939093013593505050565b600081518084526020808501945080840160005b8381101561508c57815187529582019590820190600101615070565b509495945050505050565b6040815260006150aa604083018561505c565b82810360208401526150bc818561505c565b95945050505050565b6000602082840312156150d757600080fd5b81356150e281615018565b9392505050565b6000602082840312156150fb57600080fd5b5035919050565b6000806040838503121561511557600080fd5b82359150602083013561512781615018565b809150509250929050565b6000806040838503121561514557600080fd5b50508035926020909101359150565b60ff8116811461502d57600080fd5b60008060006060848603121561517857600080fd5b83359250602084013561518a81615154565b9150604084013561519a81615018565b809150509250925092565b600080604083850312156151b857600080fd5b82356151c381615018565b9150602083013561512781615018565b801515811461502d57600080fd5b600080604083850312156151f457600080fd5b82356151ff81615018565b91506020830135615127816151d3565b600080600080600080600080610100898b03121561522c57600080fd5b883561523781615018565b9a60208a01359a5060408a013599606081013599506080810135985060a0810135975060c0810135965060e00135945092505050565b6000806040838503121561528057600080fd5b823591506020830135615127816151d3565b6020815260006150e2602083018461505c565b600080604083850312156152b857600080fd5b82356151c381615154565b6000602082840312156152d557600080fd5b81356150e281615154565b6000602082840312156152f257600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b80820260008212600160ff1b8414161561532b5761532b6152f9565b8181058314821517611b7357611b736152f9565b634e487b7160e01b600052603260045260246000fd5b600060018201615367576153676152f9565b5060010190565b80820180821115611b7357611b736152f9565b81810381811115611b7357611b736152f9565b8082028115828204841417611b7357611b736152f9565b6000826153c857634e487b7160e01b600052601260045260246000fd5b500490565b6000602082840312156153df57600080fd5b81516150e281615018565b6000602082840312156153fc57600080fd5b81516150e2816151d3565b60ff8281168282160390811115611b7357611b736152f9565b600181815b8085111561545b578160001904821115615441576154416152f9565b8085161561544e57918102915b93841c9390800290615425565b509250929050565b60008261547257506001611b73565b8161547f57506000611b73565b8160018114615495576002811461549f576154bb565b6001915050611b73565b60ff8411156154b0576154b06152f9565b50506001821b611b73565b5060208310610133831016604e8410600b84101617156154de575081810a611b73565b6154e88383615420565b80600019048211156154fc576154fc6152f9565b029392505050565b60006150e28383615463565b60006020828403121561552257600080fd5b81516150e28161515456fe546f6b656e2061646472657373206973206e6f74207365740000000000000000a164736f6c6343000811000a
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000006a005c11217863c4e300ce009c5ddc7e1672150a0000000000000000000000007ca5af5ba3472af6049f63c1abc324475d44efc1000000000000000000000000ad2e62e90c63d5c2b905c3f709cc3045aecdaa1e0000000000000000000000000fd5576c2842bd62dd00c5256491d11ccad84306000000000000000000000000ea6ab2871d5b3bbe6ded740c812d85700bae33c000000000000000000000000069a4a1cd8f2f2c3500f64634b9d69c642e9a5ca4
-----Decoded View---------------
Arg [0] : _authority (address): 0x6A005c11217863c4e300Ce009c5Ddc7e1672150A
Arg [1] : _konduxERC20 (address): 0x7CA5af5bA3472AF6049F63c1AbC324475D44EFC1
Arg [2] : _treasury (address): 0xaD2E62E90C63D5c2b905C3F709cC3045AecDAa1E
Arg [3] : _konduxERC721Founders (address): 0x0fD5576c2842bD62dd00C5256491D11CcAD84306
Arg [4] : _konduxERC721kNFT (address): 0xeA6aB2871d5B3bbe6Ded740C812D85700Bae33c0
Arg [5] : _helixERC20 (address): 0x69a4A1CD8F2f2c3500F64634B9d69C642e9A5CA4
-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 0000000000000000000000006a005c11217863c4e300ce009c5ddc7e1672150a
Arg [1] : 0000000000000000000000007ca5af5ba3472af6049f63c1abc324475d44efc1
Arg [2] : 000000000000000000000000ad2e62e90c63d5c2b905c3f709cc3045aecdaa1e
Arg [3] : 0000000000000000000000000fd5576c2842bd62dd00c5256491d11ccad84306
Arg [4] : 000000000000000000000000ea6ab2871d5b3bbe6ded740c812d85700bae33c0
Arg [5] : 00000000000000000000000069a4a1cd8f2f2c3500f64634b9d69c642e9a5ca4
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.