Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 206 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Mass Harvest | 21447487 | 2 hrs ago | IN | 0 ETH | 0.00313229 | ||||
Mass Harvest | 21248639 | 27 days ago | IN | 0 ETH | 0.00459469 | ||||
Mass Harvest | 21081492 | 51 days ago | IN | 0 ETH | 0.00487969 | ||||
Mass Harvest | 21058646 | 54 days ago | IN | 0 ETH | 0.00375398 | ||||
Mass Harvest | 21017680 | 60 days ago | IN | 0 ETH | 0.00212463 | ||||
Mass Harvest | 20987993 | 64 days ago | IN | 0 ETH | 0.00549119 | ||||
Mass Harvest | 20898783 | 76 days ago | IN | 0 ETH | 0.00050621 | ||||
Mass Harvest | 20898767 | 76 days ago | IN | 0 ETH | 0.00048319 | ||||
Mass Harvest | 20856897 | 82 days ago | IN | 0 ETH | 0.00312167 | ||||
Mass Harvest | 20839804 | 84 days ago | IN | 0 ETH | 0.00449845 | ||||
Mass Harvest | 20782603 | 92 days ago | IN | 0 ETH | 0.00397055 | ||||
Mass Harvest | 20742503 | 98 days ago | IN | 0 ETH | 0.0021758 | ||||
Mass Harvest | 20622008 | 115 days ago | IN | 0 ETH | 0.00147853 | ||||
Mass Harvest | 20588322 | 120 days ago | IN | 0 ETH | 0.00129407 | ||||
Mass Harvest | 20555845 | 124 days ago | IN | 0 ETH | 0.00067622 | ||||
Mass Harvest | 20516777 | 130 days ago | IN | 0 ETH | 0.00168308 | ||||
Mass Harvest | 20413131 | 144 days ago | IN | 0 ETH | 0.00251765 | ||||
Mass Harvest | 20336053 | 155 days ago | IN | 0 ETH | 0.00606941 | ||||
Mass Harvest | 20316208 | 158 days ago | IN | 0 ETH | 0.00241073 | ||||
Mass Harvest | 20306338 | 159 days ago | IN | 0 ETH | 0.00189438 | ||||
Mass Harvest | 20142794 | 182 days ago | IN | 0 ETH | 0.00168525 | ||||
Mass Harvest | 20090371 | 189 days ago | IN | 0 ETH | 0.00486943 | ||||
Mass Harvest | 19979685 | 205 days ago | IN | 0 ETH | 0.00348638 | ||||
Mass Harvest | 19898009 | 216 days ago | IN | 0 ETH | 0.0009928 | ||||
Mass Harvest | 19812981 | 228 days ago | IN | 0 ETH | 0.0031999 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
YieldFarmExtendedV2
Compiler Version
v0.8.4+commit.c7e474f2
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: Apache-2.0 pragma solidity ^0.8.0; // import "@openzeppelin/contracts-ethereum-package/contracts/math/SafeMath.sol"; import "@openzeppelin/contracts/utils/math/SafeMath.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "./Staking.sol"; contract YieldFarmExtendedV2 is Ownable { // lib using SafeMath for uint256; using SafeMath for uint128; // constants uint256 public constant REWARDS_PER_EPOCH = 1_750_000 ether; uint128 public constant EPOCHS_DELAYED_FROM_STAKING_CONTRACT = 65; // addreses address private _lpTokenAddress; address private _communityVault; // contracts IERC20 private _sylo; Staking private _staking; uint256[] private epochs = new uint256[](256); uint128 public lastInitializedEpoch; mapping(address => uint128) private lastEpochIdHarvested; uint256 public epochDuration; uint256 public epochStart; uint256 public finalEpoch; // events event MassHarvest( address indexed user, uint256 epochsHarvested, uint256 totalValue ); event Harvest( address indexed user, uint128 indexed epochId, uint256 amount ); // constructor constructor( address syloTokenAddress, address lpTokenAddress, Staking stakeContract, address communityVault ) { require(syloTokenAddress != address(0), "Sylo token address is required"); require(lpTokenAddress != address(0), "LP token address is required"); require(communityVault != address(0), "Community Vault address is required"); _sylo = IERC20(syloTokenAddress); _lpTokenAddress = lpTokenAddress; _staking = stakeContract; _communityVault = communityVault; epochDuration = _staking.epochDuration(); epochStart = _staking.epoch1Start() + epochDuration.mul(EPOCHS_DELAYED_FROM_STAKING_CONTRACT); } // public methods // public method to harvest all the unharvested epochs until current epoch - 1 function massHarvest() external returns (uint256) { uint256 totalDistributedValue; uint256 epochId = _getEpochId().sub(1); // fails in epoch 0 // force max number of epochs if (finalEpoch != 0 && epochId > finalEpoch) { epochId = finalEpoch; } for ( uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++ ) { // i = epochId // compute distributed Value and do one single transfer at the end totalDistributedValue += _harvest(i); } emit MassHarvest( msg.sender, epochId - lastEpochIdHarvested[msg.sender], totalDistributedValue ); if (totalDistributedValue > 0) { bool success = _sylo.transferFrom( _communityVault, msg.sender, totalDistributedValue ); require(success, "Failed to transfer mass harvest reward"); } return totalDistributedValue; } function harvest(uint128 epochId) external returns (uint256) { // checks for requested epoch require(_getEpochId() > epochId, "This epoch is in the future"); require(finalEpoch == 0 || epochId <= finalEpoch, "Cannot harvest for epochs after the yield farm has ended"); require( lastEpochIdHarvested[msg.sender].add(1) == epochId, "Harvest in order" ); uint256 userReward = _harvest(epochId); if (userReward > 0) { bool success = _sylo.transferFrom(_communityVault, msg.sender, userReward); require(success, "Failed to transfer harvest reward"); } emit Harvest(msg.sender, epochId, userReward); return userReward; } // sets the final epoch function endYieldFarm() external onlyOwner { require(finalEpoch == 0, "V2 extended yield farm has already ended"); finalEpoch = _getEpochId(); } function getEpochId() external view returns (uint256) { return _getEpochId(); } // views // calls to the staking smart contract to retrieve the epoch total pool size function getPoolSize(uint128 epochId) external view returns (uint256) { return _getPoolSize(epochId); } function getCurrentEpoch() external view returns (uint256) { return _getEpochId(); } // calls to the staking smart contract to retrieve user balance for an epoch function getEpochStake(address userAddress, uint128 epochId) external view returns (uint256) { return _getUserBalancePerEpoch(userAddress, epochId); } function userLastEpochIdHarvested() external view returns (uint256) { return lastEpochIdHarvested[msg.sender]; } // internal methods function _initEpoch(uint128 epochId) internal { require( lastInitializedEpoch.add(1) == epochId, "Epoch can be init only in order" ); lastInitializedEpoch = epochId; // call the staking smart contract to init the epoch epochs[epochId] = _getPoolSize(epochId); } function _harvest(uint128 epochId) internal returns (uint256) { // try to initialize an epoch. if it can't it fails // if it fails either user either a Plug account will init not init epochs if (lastInitializedEpoch < epochId) { _initEpoch(epochId); } // Set user state for last harvested lastEpochIdHarvested[msg.sender] = epochId; // compute and return user total reward. For optimization reasons the transfer have been moved to an upper layer (i.e. massHarvest needs to do a single transfer) // exit if there is no stake on the epoch if (epochs[epochId] == 0) { return 0; } return REWARDS_PER_EPOCH .mul(_getUserBalancePerEpoch(msg.sender, epochId)) .div(epochs[epochId]); } // retrieve _lpTokenAddress token balance function _getPoolSize(uint128 epochId) internal view returns (uint256) { return _staking.getEpochPoolSize( _lpTokenAddress, _stakingEpochId(epochId) ); } // retrieve _lpTokenAddress token balance per user per epoch function _getUserBalancePerEpoch(address userAddress, uint128 epochId) public view returns (uint256) { return _staking.getEpochUserBalance( userAddress, _lpTokenAddress, _stakingEpochId(epochId) ); } // compute epoch id from block.timestamp and epochStart date function _getEpochId() internal view returns (uint128 epochId) { if (block.timestamp < epochStart) { return 0; } epochId = uint128( block.timestamp.sub(epochStart).div(epochDuration).add(1) ); } // get the staking epoch function _stakingEpochId(uint128 epochId) internal pure returns (uint128) { return epochId + EPOCHS_DELAYED_FROM_STAKING_CONTRACT; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (utils/math/SafeMath.sol) pragma solidity ^0.8.0; // CAUTION // This version of SafeMath should only be used with Solidity 0.8 or later, // because it relies on the compiler's built in overflow checks. /** * @dev Wrappers over Solidity's arithmetic operations. * * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler * now has built in overflow checking. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { return a + b; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { return a * b; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b <= a, errorMessage); return a - b; } } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a / b; } } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a % b; } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @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 `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, 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 `sender` to `recipient` 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 sender, address recipient, uint256 amount ) external returns (bool); /** * @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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: Apache-2.0 pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/utils/math/SafeMath.sol"; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; contract Staking is ReentrancyGuard { using SafeMath for uint256; uint128 constant private BASE_MULTIPLIER = uint128(1 * 10 ** 18); // timestamp for the epoch 1 // everything before that is considered epoch 0 which won't have a reward but allows for the initial stake uint256 public epoch1Start; // duration of each epoch uint256 public epochDuration; // holds the current balance of the user for each token mapping(address => mapping(address => uint256)) private balances; struct Pool { uint256 size; bool set; } // for each token, we store the total pool size mapping(address => mapping(uint256 => Pool)) private poolSize; // a checkpoint of the valid balance of a user for an epoch struct Checkpoint { uint128 epochId; uint128 multiplier; uint256 startBalance; uint256 newDeposits; } // balanceCheckpoints[user][token][] mapping(address => mapping(address => Checkpoint[])) private balanceCheckpoints; mapping(address => uint128) private lastWithdrawEpochId; event Deposit(address indexed user, address indexed tokenAddress, uint256 amount); event Withdraw(address indexed user, address indexed tokenAddress, uint256 amount); event ManualEpochInit(address indexed caller, uint128 indexed epochId, address[] tokens); event EmergencyWithdraw(address indexed user, address indexed tokenAddress, uint256 amount); constructor (uint256 _epoch1Start, uint256 _epochDuration) { epoch1Start = _epoch1Start; epochDuration = _epochDuration; } /* * Stores `amount` of `tokenAddress` tokens for the `user` into the vault */ function deposit(address tokenAddress, uint256 amount) external nonReentrant { require(amount > 0, "Staking: Amount must be > 0"); IERC20 token = IERC20(tokenAddress); uint256 allowance = token.allowance(msg.sender, address(this)); require(allowance >= amount, "Staking: Token allowance too small"); balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].add(amount); bool success = token.transferFrom(msg.sender, address(this), amount); require(success, "Failed to transfer deposit"); // epoch logic uint128 currentEpoch = getCurrentEpoch(); uint128 currentMultiplier = currentEpochMultiplier(); if (!epochIsInitialized(tokenAddress, currentEpoch)) { address[] memory tokens = new address[](1); tokens[0] = tokenAddress; manualEpochInit(tokens, currentEpoch); } // update the next epoch pool size Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1]; pNextEpoch.size = token.balanceOf(address(this)); pNextEpoch.set = true; Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress]; uint256 balanceBefore = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch); // if there's no checkpoint yet, it means the user didn't have any activity // we want to store checkpoints both for the current epoch and next epoch because // if a user does a withdraw, the current epoch can also be modified and // we don't want to insert another checkpoint in the middle of the array as that could be expensive if (checkpoints.length == 0) { checkpoints.push(Checkpoint(currentEpoch, currentMultiplier, 0, amount)); // next epoch => multiplier is 1, epoch deposits is 0 checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, amount, 0)); } else { uint256 last = checkpoints.length - 1; // the last action happened in an older epoch (e.g. a deposit in epoch 3, current epoch is >=5) if (checkpoints[last].epochId < currentEpoch) { uint128 multiplier = computeNewMultiplier( getCheckpointBalance(checkpoints[last]), BASE_MULTIPLIER, amount, currentMultiplier ); checkpoints.push(Checkpoint(currentEpoch, multiplier, getCheckpointBalance(checkpoints[last]), amount)); uint256 balance = balances[msg.sender][tokenAddress]; checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0)); } // the last action happened in the previous epoch else if (checkpoints[last].epochId == currentEpoch) { checkpoints[last].multiplier = computeNewMultiplier( getCheckpointBalance(checkpoints[last]), checkpoints[last].multiplier, amount, currentMultiplier ); checkpoints[last].newDeposits = checkpoints[last].newDeposits.add(amount); checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balances[msg.sender][tokenAddress], 0)); } // the last action happened in the current epoch else { if (last >= 1 && checkpoints[last - 1].epochId == currentEpoch) { checkpoints[last - 1].multiplier = computeNewMultiplier( getCheckpointBalance(checkpoints[last - 1]), checkpoints[last - 1].multiplier, amount, currentMultiplier ); checkpoints[last - 1].newDeposits = checkpoints[last - 1].newDeposits.add(amount); } checkpoints[last].startBalance = balances[msg.sender][tokenAddress]; } } uint256 balanceAfter = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch); poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.add(balanceAfter.sub(balanceBefore)); emit Deposit(msg.sender, tokenAddress, amount); } /* * Removes the deposit of the user and sends the amount of `tokenAddress` back to the `user` */ function withdraw(address tokenAddress, uint256 amount) external nonReentrant { require(balances[msg.sender][tokenAddress] >= amount, "Staking: balance too small"); balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].sub(amount); IERC20 token = IERC20(tokenAddress); bool success = token.transfer(msg.sender, amount); require(success, "Failed to transfer withdrawl"); // epoch logic uint128 currentEpoch = getCurrentEpoch(); lastWithdrawEpochId[tokenAddress] = currentEpoch; if (!epochIsInitialized(tokenAddress, currentEpoch)) { address[] memory tokens = new address[](1); tokens[0] = tokenAddress; manualEpochInit(tokens, currentEpoch); } // update the pool size of the next epoch to its current balance Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1]; pNextEpoch.size = token.balanceOf(address(this)); pNextEpoch.set = true; Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress]; uint256 last = checkpoints.length - 1; // note: it's impossible to have a withdraw and no checkpoints because the balance would be 0 and revert // there was a deposit in an older epoch (more than 1 behind [eg: previous 0, now 5]) but no other action since then if (checkpoints[last].epochId < currentEpoch) { checkpoints.push(Checkpoint(currentEpoch, BASE_MULTIPLIER, balances[msg.sender][tokenAddress], 0)); poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount); } // there was a deposit in the `epochId - 1` epoch => we have a checkpoint for the current epoch else if (checkpoints[last].epochId == currentEpoch) { checkpoints[last].startBalance = balances[msg.sender][tokenAddress]; checkpoints[last].newDeposits = 0; checkpoints[last].multiplier = BASE_MULTIPLIER; poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount); } // there was a deposit in the current epoch else { Checkpoint storage currentEpochCheckpoint = checkpoints[last - 1]; uint256 balanceBefore = getCheckpointEffectiveBalance(currentEpochCheckpoint); // in case of withdraw, we have 2 branches: // 1. the user withdraws less than he added in the current epoch // 2. the user withdraws more than he added in the current epoch (including 0) if (amount < currentEpochCheckpoint.newDeposits) { uint128 avgDepositMultiplier = uint128( balanceBefore.sub(currentEpochCheckpoint.startBalance).mul(BASE_MULTIPLIER).div(currentEpochCheckpoint.newDeposits) ); currentEpochCheckpoint.newDeposits = currentEpochCheckpoint.newDeposits.sub(amount); currentEpochCheckpoint.multiplier = computeNewMultiplier( currentEpochCheckpoint.startBalance, BASE_MULTIPLIER, currentEpochCheckpoint.newDeposits, avgDepositMultiplier ); } else { currentEpochCheckpoint.startBalance = currentEpochCheckpoint.startBalance.sub( amount.sub(currentEpochCheckpoint.newDeposits) ); currentEpochCheckpoint.newDeposits = 0; currentEpochCheckpoint.multiplier = BASE_MULTIPLIER; } uint256 balanceAfter = getCheckpointEffectiveBalance(currentEpochCheckpoint); poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(balanceBefore.sub(balanceAfter)); checkpoints[last].startBalance = balances[msg.sender][tokenAddress]; } emit Withdraw(msg.sender, tokenAddress, amount); } /* * manualEpochInit can be used by anyone to initialize an epoch based on the previous one * This is only applicable if there was no action (deposit/withdraw) in the current epoch. * Any deposit and withdraw will automatically initialize the current and next epoch. */ function manualEpochInit(address[] memory tokens, uint128 epochId) public { require(epochId <= getCurrentEpoch(), "can't init a future epoch"); for (uint i = 0; i < tokens.length; i++) { Pool storage p = poolSize[tokens[i]][epochId]; if (epochId == 0) { p.size = uint256(0); p.set = true; } else { require(!epochIsInitialized(tokens[i], epochId), "Staking: epoch already initialized"); require(epochIsInitialized(tokens[i], epochId - 1), "Staking: previous epoch not initialized"); p.size = poolSize[tokens[i]][epochId - 1].size; p.set = true; } } emit ManualEpochInit(msg.sender, epochId, tokens); } function emergencyWithdraw(address tokenAddress) external { require((getCurrentEpoch() - lastWithdrawEpochId[tokenAddress]) >= 10, "At least 10 epochs must pass without success"); uint256 totalUserBalance = balances[msg.sender][tokenAddress]; require(totalUserBalance > 0, "Amount must be > 0"); balances[msg.sender][tokenAddress] = 0; IERC20 token = IERC20(tokenAddress); bool success = token.transfer(msg.sender, totalUserBalance); require(success, "Emergency withdraw transfer failed"); emit EmergencyWithdraw(msg.sender, tokenAddress, totalUserBalance); } /* * Returns the valid balance of a user that was taken into consideration in the total pool size for the epoch * A deposit will only change the next epoch balance. * A withdraw will decrease the current epoch (and subsequent) balance. */ function getEpochUserBalance(address user, address token, uint128 epochId) public view returns (uint256) { Checkpoint[] storage checkpoints = balanceCheckpoints[user][token]; // if there are no checkpoints, it means the user never deposited any tokens, so the balance is 0 if (checkpoints.length == 0 || epochId < checkpoints[0].epochId) { return 0; } uint min = 0; uint max = checkpoints.length - 1; // shortcut for blocks newer than the latest checkpoint == current balance if (epochId >= checkpoints[max].epochId) { return getCheckpointEffectiveBalance(checkpoints[max]); } // binary search of the value in the array while (max > min) { uint mid = (max + min + 1) / 2; if (checkpoints[mid].epochId <= epochId) { min = mid; } else { max = mid - 1; } } return getCheckpointEffectiveBalance(checkpoints[min]); } /* * Returns the amount of `token` that the `user` has currently staked */ function balanceOf(address user, address token) external view returns (uint256) { return balances[user][token]; } /* * Returns the id of the current epoch derived from block.timestamp */ function getCurrentEpoch() public view returns (uint128) { if (block.timestamp < epoch1Start) { return 0; } return uint128((block.timestamp - epoch1Start) / epochDuration + 1); } /* * Returns the total amount of `tokenAddress` that was locked from beginning to end of epoch identified by `epochId` */ function getEpochPoolSize(address tokenAddress, uint128 epochId) external view returns (uint256) { // Premises: // 1. it's impossible to have gaps of uninitialized epochs // - any deposit or withdraw initialize the current epoch which requires the previous one to be initialized if (epochIsInitialized(tokenAddress, epochId)) { return poolSize[tokenAddress][epochId].size; } // epochId not initialized and epoch 0 not initialized => there was never any action on this pool if (!epochIsInitialized(tokenAddress, 0)) { return 0; } // epoch 0 is initialized => there was an action at some point but none that initialized the epochId // which means the current pool size is equal to the current balance of token held by the staking contract IERC20 token = IERC20(tokenAddress); return token.balanceOf(address(this)); } /* * Returns the percentage of time left in the current epoch */ function currentEpochMultiplier() public view returns (uint128) { uint128 currentEpoch = getCurrentEpoch(); uint256 currentEpochEnd = epoch1Start + currentEpoch * epochDuration; uint256 timeLeft = currentEpochEnd - block.timestamp; uint128 multiplier = uint128(timeLeft * BASE_MULTIPLIER / epochDuration); return multiplier; } function computeNewMultiplier(uint256 prevBalance, uint128 prevMultiplier, uint256 amount, uint128 currentMultiplier) public pure returns (uint128) { uint256 prevAmount = prevBalance.mul(prevMultiplier).div(BASE_MULTIPLIER); uint256 addAmount = amount.mul(currentMultiplier).div(BASE_MULTIPLIER); uint128 newMultiplier = uint128(prevAmount.add(addAmount).mul(BASE_MULTIPLIER).div(prevBalance.add(amount))); return newMultiplier; } /* * Checks if an epoch is initialized, meaning we have a pool size set for it */ function epochIsInitialized(address token, uint128 epochId) public view returns (bool) { return poolSize[token][epochId].set; } function getCheckpointBalance(Checkpoint memory c) internal pure returns (uint256) { return c.startBalance.add(c.newDeposits); } function getCheckpointEffectiveBalance(Checkpoint memory c) internal pure returns (uint256) { return getCheckpointBalance(c).mul(c.multiplier).div(BASE_MULTIPLIER); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
{ "optimizer": { "enabled": false, "runs": 200 }, "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":"syloTokenAddress","type":"address"},{"internalType":"address","name":"lpTokenAddress","type":"address"},{"internalType":"contract Staking","name":"stakeContract","type":"address"},{"internalType":"address","name":"communityVault","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint128","name":"epochId","type":"uint128"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Harvest","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"epochsHarvested","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalValue","type":"uint256"}],"name":"MassHarvest","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"EPOCHS_DELAYED_FROM_STAKING_CONTRACT","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REWARDS_PER_EPOCH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"uint128","name":"epochId","type":"uint128"}],"name":"_getUserBalancePerEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"endYieldFarm","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"epochDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"epochStart","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"finalEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getEpochId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"uint128","name":"epochId","type":"uint128"}],"name":"getEpochStake","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint128","name":"epochId","type":"uint128"}],"name":"getPoolSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint128","name":"epochId","type":"uint128"}],"name":"harvest","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lastInitializedEpoch","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"massHarvest","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"userLastEpochIdHarvested","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405261010067ffffffffffffffff81111562000047577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051908082528060200260200182016040528015620000765781602001602082028036833780820191505090505b50600590805190602001906200008e929190620005bc565b503480156200009c57600080fd5b50604051620027b9380380620027b98339818101604052810190620000c2919062000672565b620000e2620000d6620004d860201b60201c565b620004e060201b60201c565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16141562000155576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200014c906200077f565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415620001c8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620001bf90620007a1565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156200023b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200023290620007c3565b60405180910390fd5b83600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634ff0876a6040518163ffffffff1660e01b815260040160206040518083038186803b158015620003a857600080fd5b505afa158015620003bd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003e39190620006de565b6008819055506200041860416fffffffffffffffffffffffffffffffff16600854620005a460201b62000e1e1790919060201c565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f4a4341d6040518163ffffffff1660e01b815260040160206040518083038186803b1580156200048157600080fd5b505afa15801562000496573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620004bc9190620006de565b620004c89190620007f6565b6009819055505050505062000a24565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60008183620005b4919062000853565b905092915050565b828054828255906000526020600020908101928215620005fb579160200282015b82811115620005fa578251825591602001919060010190620005dd565b5b5090506200060a91906200060e565b5090565b5b80821115620006295760008160009055506001016200060f565b5090565b6000815190506200063e81620009d6565b92915050565b6000815190506200065581620009f0565b92915050565b6000815190506200066c8162000a0a565b92915050565b600080600080608085870312156200068957600080fd5b600062000699878288016200062d565b9450506020620006ac878288016200062d565b9350506040620006bf8782880162000644565b9250506060620006d2878288016200062d565b91505092959194509250565b600060208284031215620006f157600080fd5b600062000701848285016200065b565b91505092915050565b600062000719601e83620007e5565b9150620007268262000935565b602082019050919050565b600062000740601c83620007e5565b91506200074d826200095e565b602082019050919050565b600062000767602383620007e5565b9150620007748262000987565b604082019050919050565b600060208201905081810360008301526200079a816200070a565b9050919050565b60006020820190508181036000830152620007bc8162000731565b9050919050565b60006020820190508181036000830152620007de8162000758565b9050919050565b600082825260208201905092915050565b60006200080382620008fc565b91506200081083620008fc565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111562000848576200084762000906565b5b828201905092915050565b60006200086082620008fc565b91506200086d83620008fc565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615620008a957620008a862000906565b5b828202905092915050565b6000620008c182620008dc565b9050919050565b6000620008d582620008b4565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f53796c6f20746f6b656e20616464726573732069732072657175697265640000600082015250565b7f4c5020746f6b656e206164647265737320697320726571756972656400000000600082015250565b7f436f6d6d756e697479205661756c74206164647265737320697320726571756960008201527f7265640000000000000000000000000000000000000000000000000000000000602082015250565b620009e181620008b4565b8114620009ed57600080fd5b50565b620009fb81620008c8565b811462000a0757600080fd5b50565b62000a1581620008fc565b811462000a2157600080fd5b50565b611d858062000a346000396000f3fe608060405234801561001057600080fd5b50600436106101165760003560e01c80639c7ec881116100a2578063b97dd9e211610071578063b97dd9e2146102b1578063ce9dfc95146102cf578063dc2269f1146102ff578063f2fde38b14610309578063f7e251f81461032557610116565b80639c7ec88114610227578063a1c130d414610245578063a43564eb14610263578063a6ace8a31461029357610116565b80634ff0876a116100e95780634ff0876a146101a55780636ef8ad23146101c3578063715018a6146101e15780637d36a410146101eb5780638da5cb5b1461020957610116565b806315e5a1e51461011b578063290e4544146101395780633a98d88e146101575780634331245114610175575b600080fd5b610123610355565b6040516101309190611819565b60405180910390f35b61014161035b565b60405161014e9190611819565b60405180910390f35b61015f610650565b60405161016c9190611819565b60405180910390f35b61018f600480360381019061018a919061140d565b610656565b60405161019c9190611819565b60405180910390f35b6101ad61066a565b6040516101ba9190611819565b60405180910390f35b6101cb610670565b6040516101d89190611819565b60405180910390f35b6101e961067f565b005b6101f3610707565b6040516102009190611819565b60405180910390f35b610211610728565b60405161021e919061162c565b60405180910390f35b61022f610751565b60405161023c91906117fe565b60405180910390f35b61024d610773565b60405161025a9190611819565b60405180910390f35b61027d60048036038101906102789190611472565b6107e8565b60405161028a9190611819565b60405180910390f35b61029b610b28565b6040516102a891906117fe565b60405180910390f35b6102b9610b2d565b6040516102c69190611819565b60405180910390f35b6102e960048036038101906102e4919061140d565b610b4e565b6040516102f69190611819565b60405180910390f35b610307610c31565b005b610323600480360381019061031e91906113e4565b610d14565b005b61033f600480360381019061033a9190611472565b610e0c565b60405161034c9190611819565b60405180910390f35b60095481565b600080600061038d600161036d610e34565b6fffffffffffffffffffffffffffffffff16610e8b90919063ffffffff16565b90506000600a54141580156103a35750600a5481115b156103ae57600a5490505b60006001600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a90046fffffffffffffffffffffffffffffffff16610418919061186e565b90505b81816fffffffffffffffffffffffffffffffff161161045d5761043d81610ea1565b8361044891906118b4565b9250808061045590611a2d565b91505061041b565b503373ffffffffffffffffffffffffffffffffffffffff167fb68dafc1da13dc868096d0b87347c831d0bda92d178317eb1dec7f788444485c600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff168361050f9190611995565b8460405161051e929190611834565b60405180910390a26000821115610648576000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1633866040518463ffffffff1660e01b81526004016105b29392919061167e565b602060405180830381600087803b1580156105cc57600080fd5b505af11580156105e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106049190611449565b905080610646576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161063d906117be565b60405180910390fd5b505b819250505090565b600a5481565b60006106628383610b4e565b905092915050565b60085481565b6a017293b0a9e69fd9c0000081565b61068761106c565b73ffffffffffffffffffffffffffffffffffffffff166106a5610728565b73ffffffffffffffffffffffffffffffffffffffff16146106fb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106f29061171e565b60405180910390fd5b6107056000611074565b565b6000610711610e34565b6fffffffffffffffffffffffffffffffff16905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600660009054906101000a90046fffffffffffffffffffffffffffffffff1681565b6000600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16905090565b6000816fffffffffffffffffffffffffffffffff16610805610e34565b6fffffffffffffffffffffffffffffffff1611610857576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161084e906117de565b60405180910390fd5b6000600a54148061087c5750600a54826fffffffffffffffffffffffffffffffff1611155b6108bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108b29061179e565b60405180910390fd5b816fffffffffffffffffffffffffffffffff1661094f6001600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1661113890919063ffffffff16565b1461098f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109869061173e565b60405180910390fd5b600061099a83610ea1565b90506000811115610abe576000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1633856040518463ffffffff1660e01b8152600401610a289392919061167e565b602060405180830381600087803b158015610a4257600080fd5b505af1158015610a56573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a7a9190611449565b905080610abc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ab39061177e565b60405180910390fd5b505b826fffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f04ad45a69eeed9c390c3a678fed2d4b90bde98e742de9936d5e0915bf3d0ea4e83604051610b179190611819565b60405180910390a380915050919050565b604181565b6000610b37610e34565b6fffffffffffffffffffffffffffffffff16905090565b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638c028dd084600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16610bbb8661114e565b6040518463ffffffff1660e01b8152600401610bd993929190611647565b60206040518083038186803b158015610bf157600080fd5b505afa158015610c05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c29919061149b565b905092915050565b610c3961106c565b73ffffffffffffffffffffffffffffffffffffffff16610c57610728565b73ffffffffffffffffffffffffffffffffffffffff1614610cad576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ca49061171e565b60405180910390fd5b6000600a5414610cf2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ce99061175e565b60405180910390fd5b610cfa610e34565b6fffffffffffffffffffffffffffffffff16600a81905550565b610d1c61106c565b73ffffffffffffffffffffffffffffffffffffffff16610d3a610728565b73ffffffffffffffffffffffffffffffffffffffff1614610d90576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d879061171e565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610e00576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610df7906116de565b60405180910390fd5b610e0981611074565b50565b6000610e1782611164565b9050919050565b60008183610e2c919061193b565b905092915050565b6000600954421015610e495760009050610e88565b610e856001610e77600854610e6960095442610e8b90919063ffffffff16565b61124490919063ffffffff16565b61113890919063ffffffff16565b90505b90565b60008183610e999190611995565b905092915050565b6000816fffffffffffffffffffffffffffffffff16600660009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff161015610ef757610ef68261125a565b5b81600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060006005836fffffffffffffffffffffffffffffffff1681548110610fbb577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001541415610fd55760009050611067565b6110646005836fffffffffffffffffffffffffffffffff1681548110611024577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020015461105661103c3386610b4e565b6a017293b0a9e69fd9c00000610e1e90919063ffffffff16565b61124490919063ffffffff16565b90505b919050565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000818361114691906118b4565b905092915050565b600060418261115d919061186e565b9050919050565b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632ca32d7e600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166111d08561114e565b6040518363ffffffff1660e01b81526004016111ed9291906116b5565b60206040518083038186803b15801561120557600080fd5b505afa158015611219573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061123d919061149b565b9050919050565b60008183611252919061190a565b905092915050565b806fffffffffffffffffffffffffffffffff166112b16001600660009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1661113890919063ffffffff16565b146112f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112e8906116fe565b60405180910390fd5b80600660006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555061133381611164565b6005826fffffffffffffffffffffffffffffffff168154811061137f577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020018190555050565b60008135905061139f81611cf3565b92915050565b6000815190506113b481611d0a565b92915050565b6000813590506113c981611d21565b92915050565b6000815190506113de81611d38565b92915050565b6000602082840312156113f657600080fd5b600061140484828501611390565b91505092915050565b6000806040838503121561142057600080fd5b600061142e85828601611390565b925050602061143f858286016113ba565b9150509250929050565b60006020828403121561145b57600080fd5b6000611469848285016113a5565b91505092915050565b60006020828403121561148457600080fd5b6000611492848285016113ba565b91505092915050565b6000602082840312156114ad57600080fd5b60006114bb848285016113cf565b91505092915050565b6114cd816119c9565b82525050565b60006114e060268361185d565b91506114eb82611ac4565b604082019050919050565b6000611503601f8361185d565b915061150e82611b13565b602082019050919050565b600061152660208361185d565b915061153182611b3c565b602082019050919050565b600061154960108361185d565b915061155482611b65565b602082019050919050565b600061156c60288361185d565b915061157782611b8e565b604082019050919050565b600061158f60218361185d565b915061159a82611bdd565b604082019050919050565b60006115b260388361185d565b91506115bd82611c2c565b604082019050919050565b60006115d560268361185d565b91506115e082611c7b565b604082019050919050565b60006115f8601b8361185d565b915061160382611cca565b602082019050919050565b611617816119e7565b82525050565b61162681611a23565b82525050565b600060208201905061164160008301846114c4565b92915050565b600060608201905061165c60008301866114c4565b61166960208301856114c4565b611676604083018461160e565b949350505050565b600060608201905061169360008301866114c4565b6116a060208301856114c4565b6116ad604083018461161d565b949350505050565b60006040820190506116ca60008301856114c4565b6116d7602083018461160e565b9392505050565b600060208201905081810360008301526116f7816114d3565b9050919050565b60006020820190508181036000830152611717816114f6565b9050919050565b6000602082019050818103600083015261173781611519565b9050919050565b600060208201905081810360008301526117578161153c565b9050919050565b600060208201905081810360008301526117778161155f565b9050919050565b6000602082019050818103600083015261179781611582565b9050919050565b600060208201905081810360008301526117b7816115a5565b9050919050565b600060208201905081810360008301526117d7816115c8565b9050919050565b600060208201905081810360008301526117f7816115eb565b9050919050565b6000602082019050611813600083018461160e565b92915050565b600060208201905061182e600083018461161d565b92915050565b6000604082019050611849600083018561161d565b611856602083018461161d565b9392505050565b600082825260208201905092915050565b6000611879826119e7565b9150611884836119e7565b9250826fffffffffffffffffffffffffffffffff038211156118a9576118a8611a66565b5b828201905092915050565b60006118bf82611a23565b91506118ca83611a23565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156118ff576118fe611a66565b5b828201905092915050565b600061191582611a23565b915061192083611a23565b9250826119305761192f611a95565b5b828204905092915050565b600061194682611a23565b915061195183611a23565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561198a57611989611a66565b5b828202905092915050565b60006119a082611a23565b91506119ab83611a23565b9250828210156119be576119bd611a66565b5b828203905092915050565b60006119d482611a03565b9050919050565b60008115159050919050565b60006fffffffffffffffffffffffffffffffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b6000611a38826119e7565b91506fffffffffffffffffffffffffffffffff821415611a5b57611a5a611a66565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f45706f63682063616e20626520696e6974206f6e6c7920696e206f7264657200600082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f4861727665737420696e206f7264657200000000000000000000000000000000600082015250565b7f563220657874656e646564207969656c64206661726d2068617320616c72656160008201527f647920656e646564000000000000000000000000000000000000000000000000602082015250565b7f4661696c656420746f207472616e73666572206861727665737420726577617260008201527f6400000000000000000000000000000000000000000000000000000000000000602082015250565b7f43616e6e6f74206861727665737420666f722065706f6368732061667465722060008201527f746865207969656c64206661726d2068617320656e6465640000000000000000602082015250565b7f4661696c656420746f207472616e73666572206d61737320686172766573742060008201527f7265776172640000000000000000000000000000000000000000000000000000602082015250565b7f546869732065706f636820697320696e20746865206675747572650000000000600082015250565b611cfc816119c9565b8114611d0757600080fd5b50565b611d13816119db565b8114611d1e57600080fd5b50565b611d2a816119e7565b8114611d3557600080fd5b50565b611d4181611a23565b8114611d4c57600080fd5b5056fea264697066735822122039061b7b51ed03414f9ffe9e287fcc39dc6a57a6aa977e36d0bdcc4fabd9100864736f6c63430008040033000000000000000000000000f293d23bf2cdc05411ca0eddd588eb1977e8dcd40000000000000000000000002a66392317698c5818df7a72a58556049f0ae6f2000000000000000000000000f52ca8c3812ba6b0d820deba852ae781a39fefe700000000000000000000000087eb64e695f1a40a8e86a0cc605a263475221960
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101165760003560e01c80639c7ec881116100a2578063b97dd9e211610071578063b97dd9e2146102b1578063ce9dfc95146102cf578063dc2269f1146102ff578063f2fde38b14610309578063f7e251f81461032557610116565b80639c7ec88114610227578063a1c130d414610245578063a43564eb14610263578063a6ace8a31461029357610116565b80634ff0876a116100e95780634ff0876a146101a55780636ef8ad23146101c3578063715018a6146101e15780637d36a410146101eb5780638da5cb5b1461020957610116565b806315e5a1e51461011b578063290e4544146101395780633a98d88e146101575780634331245114610175575b600080fd5b610123610355565b6040516101309190611819565b60405180910390f35b61014161035b565b60405161014e9190611819565b60405180910390f35b61015f610650565b60405161016c9190611819565b60405180910390f35b61018f600480360381019061018a919061140d565b610656565b60405161019c9190611819565b60405180910390f35b6101ad61066a565b6040516101ba9190611819565b60405180910390f35b6101cb610670565b6040516101d89190611819565b60405180910390f35b6101e961067f565b005b6101f3610707565b6040516102009190611819565b60405180910390f35b610211610728565b60405161021e919061162c565b60405180910390f35b61022f610751565b60405161023c91906117fe565b60405180910390f35b61024d610773565b60405161025a9190611819565b60405180910390f35b61027d60048036038101906102789190611472565b6107e8565b60405161028a9190611819565b60405180910390f35b61029b610b28565b6040516102a891906117fe565b60405180910390f35b6102b9610b2d565b6040516102c69190611819565b60405180910390f35b6102e960048036038101906102e4919061140d565b610b4e565b6040516102f69190611819565b60405180910390f35b610307610c31565b005b610323600480360381019061031e91906113e4565b610d14565b005b61033f600480360381019061033a9190611472565b610e0c565b60405161034c9190611819565b60405180910390f35b60095481565b600080600061038d600161036d610e34565b6fffffffffffffffffffffffffffffffff16610e8b90919063ffffffff16565b90506000600a54141580156103a35750600a5481115b156103ae57600a5490505b60006001600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a90046fffffffffffffffffffffffffffffffff16610418919061186e565b90505b81816fffffffffffffffffffffffffffffffff161161045d5761043d81610ea1565b8361044891906118b4565b9250808061045590611a2d565b91505061041b565b503373ffffffffffffffffffffffffffffffffffffffff167fb68dafc1da13dc868096d0b87347c831d0bda92d178317eb1dec7f788444485c600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff168361050f9190611995565b8460405161051e929190611834565b60405180910390a26000821115610648576000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1633866040518463ffffffff1660e01b81526004016105b29392919061167e565b602060405180830381600087803b1580156105cc57600080fd5b505af11580156105e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106049190611449565b905080610646576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161063d906117be565b60405180910390fd5b505b819250505090565b600a5481565b60006106628383610b4e565b905092915050565b60085481565b6a017293b0a9e69fd9c0000081565b61068761106c565b73ffffffffffffffffffffffffffffffffffffffff166106a5610728565b73ffffffffffffffffffffffffffffffffffffffff16146106fb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106f29061171e565b60405180910390fd5b6107056000611074565b565b6000610711610e34565b6fffffffffffffffffffffffffffffffff16905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600660009054906101000a90046fffffffffffffffffffffffffffffffff1681565b6000600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16905090565b6000816fffffffffffffffffffffffffffffffff16610805610e34565b6fffffffffffffffffffffffffffffffff1611610857576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161084e906117de565b60405180910390fd5b6000600a54148061087c5750600a54826fffffffffffffffffffffffffffffffff1611155b6108bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108b29061179e565b60405180910390fd5b816fffffffffffffffffffffffffffffffff1661094f6001600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1661113890919063ffffffff16565b1461098f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109869061173e565b60405180910390fd5b600061099a83610ea1565b90506000811115610abe576000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1633856040518463ffffffff1660e01b8152600401610a289392919061167e565b602060405180830381600087803b158015610a4257600080fd5b505af1158015610a56573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a7a9190611449565b905080610abc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ab39061177e565b60405180910390fd5b505b826fffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f04ad45a69eeed9c390c3a678fed2d4b90bde98e742de9936d5e0915bf3d0ea4e83604051610b179190611819565b60405180910390a380915050919050565b604181565b6000610b37610e34565b6fffffffffffffffffffffffffffffffff16905090565b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638c028dd084600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16610bbb8661114e565b6040518463ffffffff1660e01b8152600401610bd993929190611647565b60206040518083038186803b158015610bf157600080fd5b505afa158015610c05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c29919061149b565b905092915050565b610c3961106c565b73ffffffffffffffffffffffffffffffffffffffff16610c57610728565b73ffffffffffffffffffffffffffffffffffffffff1614610cad576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ca49061171e565b60405180910390fd5b6000600a5414610cf2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ce99061175e565b60405180910390fd5b610cfa610e34565b6fffffffffffffffffffffffffffffffff16600a81905550565b610d1c61106c565b73ffffffffffffffffffffffffffffffffffffffff16610d3a610728565b73ffffffffffffffffffffffffffffffffffffffff1614610d90576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d879061171e565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610e00576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610df7906116de565b60405180910390fd5b610e0981611074565b50565b6000610e1782611164565b9050919050565b60008183610e2c919061193b565b905092915050565b6000600954421015610e495760009050610e88565b610e856001610e77600854610e6960095442610e8b90919063ffffffff16565b61124490919063ffffffff16565b61113890919063ffffffff16565b90505b90565b60008183610e999190611995565b905092915050565b6000816fffffffffffffffffffffffffffffffff16600660009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff161015610ef757610ef68261125a565b5b81600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060006005836fffffffffffffffffffffffffffffffff1681548110610fbb577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001541415610fd55760009050611067565b6110646005836fffffffffffffffffffffffffffffffff1681548110611024577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020015461105661103c3386610b4e565b6a017293b0a9e69fd9c00000610e1e90919063ffffffff16565b61124490919063ffffffff16565b90505b919050565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000818361114691906118b4565b905092915050565b600060418261115d919061186e565b9050919050565b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632ca32d7e600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166111d08561114e565b6040518363ffffffff1660e01b81526004016111ed9291906116b5565b60206040518083038186803b15801561120557600080fd5b505afa158015611219573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061123d919061149b565b9050919050565b60008183611252919061190a565b905092915050565b806fffffffffffffffffffffffffffffffff166112b16001600660009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1661113890919063ffffffff16565b146112f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112e8906116fe565b60405180910390fd5b80600660006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555061133381611164565b6005826fffffffffffffffffffffffffffffffff168154811061137f577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020018190555050565b60008135905061139f81611cf3565b92915050565b6000815190506113b481611d0a565b92915050565b6000813590506113c981611d21565b92915050565b6000815190506113de81611d38565b92915050565b6000602082840312156113f657600080fd5b600061140484828501611390565b91505092915050565b6000806040838503121561142057600080fd5b600061142e85828601611390565b925050602061143f858286016113ba565b9150509250929050565b60006020828403121561145b57600080fd5b6000611469848285016113a5565b91505092915050565b60006020828403121561148457600080fd5b6000611492848285016113ba565b91505092915050565b6000602082840312156114ad57600080fd5b60006114bb848285016113cf565b91505092915050565b6114cd816119c9565b82525050565b60006114e060268361185d565b91506114eb82611ac4565b604082019050919050565b6000611503601f8361185d565b915061150e82611b13565b602082019050919050565b600061152660208361185d565b915061153182611b3c565b602082019050919050565b600061154960108361185d565b915061155482611b65565b602082019050919050565b600061156c60288361185d565b915061157782611b8e565b604082019050919050565b600061158f60218361185d565b915061159a82611bdd565b604082019050919050565b60006115b260388361185d565b91506115bd82611c2c565b604082019050919050565b60006115d560268361185d565b91506115e082611c7b565b604082019050919050565b60006115f8601b8361185d565b915061160382611cca565b602082019050919050565b611617816119e7565b82525050565b61162681611a23565b82525050565b600060208201905061164160008301846114c4565b92915050565b600060608201905061165c60008301866114c4565b61166960208301856114c4565b611676604083018461160e565b949350505050565b600060608201905061169360008301866114c4565b6116a060208301856114c4565b6116ad604083018461161d565b949350505050565b60006040820190506116ca60008301856114c4565b6116d7602083018461160e565b9392505050565b600060208201905081810360008301526116f7816114d3565b9050919050565b60006020820190508181036000830152611717816114f6565b9050919050565b6000602082019050818103600083015261173781611519565b9050919050565b600060208201905081810360008301526117578161153c565b9050919050565b600060208201905081810360008301526117778161155f565b9050919050565b6000602082019050818103600083015261179781611582565b9050919050565b600060208201905081810360008301526117b7816115a5565b9050919050565b600060208201905081810360008301526117d7816115c8565b9050919050565b600060208201905081810360008301526117f7816115eb565b9050919050565b6000602082019050611813600083018461160e565b92915050565b600060208201905061182e600083018461161d565b92915050565b6000604082019050611849600083018561161d565b611856602083018461161d565b9392505050565b600082825260208201905092915050565b6000611879826119e7565b9150611884836119e7565b9250826fffffffffffffffffffffffffffffffff038211156118a9576118a8611a66565b5b828201905092915050565b60006118bf82611a23565b91506118ca83611a23565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156118ff576118fe611a66565b5b828201905092915050565b600061191582611a23565b915061192083611a23565b9250826119305761192f611a95565b5b828204905092915050565b600061194682611a23565b915061195183611a23565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561198a57611989611a66565b5b828202905092915050565b60006119a082611a23565b91506119ab83611a23565b9250828210156119be576119bd611a66565b5b828203905092915050565b60006119d482611a03565b9050919050565b60008115159050919050565b60006fffffffffffffffffffffffffffffffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b6000611a38826119e7565b91506fffffffffffffffffffffffffffffffff821415611a5b57611a5a611a66565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f45706f63682063616e20626520696e6974206f6e6c7920696e206f7264657200600082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f4861727665737420696e206f7264657200000000000000000000000000000000600082015250565b7f563220657874656e646564207969656c64206661726d2068617320616c72656160008201527f647920656e646564000000000000000000000000000000000000000000000000602082015250565b7f4661696c656420746f207472616e73666572206861727665737420726577617260008201527f6400000000000000000000000000000000000000000000000000000000000000602082015250565b7f43616e6e6f74206861727665737420666f722065706f6368732061667465722060008201527f746865207969656c64206661726d2068617320656e6465640000000000000000602082015250565b7f4661696c656420746f207472616e73666572206d61737320686172766573742060008201527f7265776172640000000000000000000000000000000000000000000000000000602082015250565b7f546869732065706f636820697320696e20746865206675747572650000000000600082015250565b611cfc816119c9565b8114611d0757600080fd5b50565b611d13816119db565b8114611d1e57600080fd5b50565b611d2a816119e7565b8114611d3557600080fd5b50565b611d4181611a23565b8114611d4c57600080fd5b5056fea264697066735822122039061b7b51ed03414f9ffe9e287fcc39dc6a57a6aa977e36d0bdcc4fabd9100864736f6c63430008040033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000f293d23bf2cdc05411ca0eddd588eb1977e8dcd40000000000000000000000002a66392317698c5818df7a72a58556049f0ae6f2000000000000000000000000f52ca8c3812ba6b0d820deba852ae781a39fefe700000000000000000000000087eb64e695f1a40a8e86a0cc605a263475221960
-----Decoded View---------------
Arg [0] : syloTokenAddress (address): 0xf293d23BF2CDc05411Ca0edDD588eb1977e8dcd4
Arg [1] : lpTokenAddress (address): 0x2A66392317698C5818df7A72a58556049f0Ae6f2
Arg [2] : stakeContract (address): 0xF52CA8C3812ba6B0D820DEbA852Ae781a39FeFe7
Arg [3] : communityVault (address): 0x87eb64E695f1a40a8E86a0Cc605A263475221960
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000f293d23bf2cdc05411ca0eddd588eb1977e8dcd4
Arg [1] : 0000000000000000000000002a66392317698c5818df7a72a58556049f0ae6f2
Arg [2] : 000000000000000000000000f52ca8c3812ba6b0d820deba852ae781a39fefe7
Arg [3] : 00000000000000000000000087eb64e695f1a40a8e86a0cc605a263475221960
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.