Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 386 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Mass Harvest | 21348632 | 13 days ago | IN | 0 ETH | 0.00146279 | ||||
Mass Harvest | 21248641 | 27 days ago | IN | 0 ETH | 0.00619278 | ||||
Mass Harvest | 21058648 | 54 days ago | IN | 0 ETH | 0.00486138 | ||||
Mass Harvest | 21017704 | 60 days ago | IN | 0 ETH | 0.0025879 | ||||
Mass Harvest | 20839817 | 84 days ago | IN | 0 ETH | 0.00611421 | ||||
Mass Harvest | 20782591 | 92 days ago | IN | 0 ETH | 0.00559276 | ||||
Mass Harvest | 20742551 | 98 days ago | IN | 0 ETH | 0.00269304 | ||||
Mass Harvest | 20588324 | 120 days ago | IN | 0 ETH | 0.00175108 | ||||
Mass Harvest | 20516774 | 130 days ago | IN | 0 ETH | 0.00235651 | ||||
Mass Harvest | 20336055 | 155 days ago | IN | 0 ETH | 0.00565978 | ||||
Mass Harvest | 20306339 | 159 days ago | IN | 0 ETH | 0.00255936 | ||||
Mass Harvest | 19813031 | 228 days ago | IN | 0 ETH | 0.00481801 | ||||
Mass Harvest | 19693303 | 245 days ago | IN | 0 ETH | 0.00402458 | ||||
Mass Harvest | 19586788 | 260 days ago | IN | 0 ETH | 0.00791325 | ||||
Mass Harvest | 19569816 | 262 days ago | IN | 0 ETH | 0.0228258 | ||||
Mass Harvest | 19534796 | 267 days ago | IN | 0 ETH | 0.00606502 | ||||
Mass Harvest | 19493801 | 273 days ago | IN | 0 ETH | 0.01085447 | ||||
Mass Harvest | 19473596 | 275 days ago | IN | 0 ETH | 0.01968438 | ||||
Mass Harvest | 19420809 | 283 days ago | IN | 0 ETH | 0.0333006 | ||||
Mass Harvest | 19109720 | 326 days ago | IN | 0 ETH | 0.00590149 | ||||
Mass Harvest | 18819625 | 367 days ago | IN | 0 ETH | 0.02866189 | ||||
Mass Harvest | 18759293 | 376 days ago | IN | 0 ETH | 0.01229293 | ||||
Mass Harvest | 18733270 | 379 days ago | IN | 0 ETH | 0.02265085 | ||||
Mass Harvest | 18732998 | 379 days ago | IN | 0 ETH | 0.01750798 | ||||
Mass Harvest | 18703417 | 383 days ago | IN | 0 ETH | 0.01179727 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
YieldFarmExtended
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 "./Staking.sol"; contract YieldFarmExtended { // lib using SafeMath for uint256; using SafeMath for uint128; // constants uint256 public constant TOTAL_DISTRIBUTED_AMOUNT = 70_000_000; uint256 public constant NR_OF_EPOCHS = 40; uint128 public constant EPOCHS_DELAYED_FROM_STAKING_CONTRACT = 25; // addreses address private _lpTokenAddress; address private _communityVault; // contracts IERC20 private _sylo; Staking private _staking; uint256[] private epochs = new uint256[](NR_OF_EPOCHS + 1); uint256 private _totalAmountPerEpoch; uint128 public lastInitializedEpoch; mapping(address => uint128) private lastEpochIdHarvested; uint256 public epochDuration; uint256 public epochStart; // 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); _totalAmountPerEpoch = TOTAL_DISTRIBUTED_AMOUNT .mul(10**18) .div(NR_OF_EPOCHS); } // 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 (epochId > NR_OF_EPOCHS) { epochId = NR_OF_EPOCHS; } 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(epochId <= NR_OF_EPOCHS, "Maximum number of epochs is 12"); 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; } // 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 _totalAmountPerEpoch .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) internal 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: 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 (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"},{"inputs":[],"name":"EPOCHS_DELAYED_FROM_STAKING_CONTRACT","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NR_OF_EPOCHS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TOTAL_DISTRIBUTED_AMOUNT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":"getCurrentEpoch","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":"userLastEpochIdHarvested","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60806040526001602862000014919062000774565b67ffffffffffffffff81111562000054577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051908082528060200260200182016040528015620000835781602001602082028036833780820191505090505b50600490805190602001906200009b9291906200053a565b50348015620000a957600080fd5b50604051620020f9380380620020f98339818101604052810190620000cf9190620005f0565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16141562000142576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200013990620006fd565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415620001b5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620001ac906200071f565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141562000228576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200021f9062000741565b60405180910390fd5b83600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550826000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634ff0876a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156200039457600080fd5b505afa158015620003a9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003cf91906200065c565b6008819055506200040460196fffffffffffffffffffffffffffffffff166008546200050a60201b620009691790919060201c565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f4a4341d6040518163ffffffff1660e01b815260040160206040518083038186803b1580156200046d57600080fd5b505afa15801562000482573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620004a891906200065c565b620004b4919062000774565b600981905550620004fa6028620004e6670de0b6b3a764000063042c1d806200050a60201b620009691790919060201c565b6200052260201b6200097f1790919060201c565b6005819055505050505062000a09565b600081836200051a919062000809565b905092915050565b60008183620005329190620007d1565b905092915050565b82805482825590600052602060002090810192821562000579579160200282015b82811115620005785782518255916020019190600101906200055b565b5b5090506200058891906200058c565b5090565b5b80821115620005a75760008160009055506001016200058d565b5090565b600081519050620005bc81620009bb565b92915050565b600081519050620005d381620009d5565b92915050565b600081519050620005ea81620009ef565b92915050565b600080600080608085870312156200060757600080fd5b60006200061787828801620005ab565b94505060206200062a87828801620005ab565b93505060406200063d87828801620005c2565b92505060606200065087828801620005ab565b91505092959194509250565b6000602082840312156200066f57600080fd5b60006200067f84828501620005d9565b91505092915050565b600062000697601e8362000763565b9150620006a4826200091a565b602082019050919050565b6000620006be601c8362000763565b9150620006cb8262000943565b602082019050919050565b6000620006e560238362000763565b9150620006f2826200096c565b604082019050919050565b60006020820190508181036000830152620007188162000688565b9050919050565b600060208201905081810360008301526200073a81620006af565b9050919050565b600060208201905081810360008301526200075c81620006d6565b9050919050565b600082825260208201905092915050565b60006200078182620008b2565b91506200078e83620008b2565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115620007c657620007c5620008bc565b5b828201905092915050565b6000620007de82620008b2565b9150620007eb83620008b2565b925082620007fe57620007fd620008eb565b5b828204905092915050565b60006200081682620008b2565b91506200082383620008b2565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156200085f576200085e620008bc565b5b828202905092915050565b6000620008778262000892565b9050919050565b60006200088b826200086a565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f53796c6f20746f6b656e20616464726573732069732072657175697265640000600082015250565b7f4c5020746f6b656e206164647265737320697320726571756972656400000000600082015250565b7f436f6d6d756e697479205661756c74206164647265737320697320726571756960008201527f7265640000000000000000000000000000000000000000000000000000000000602082015250565b620009c6816200086a565b8114620009d257600080fd5b50565b620009e0816200087e565b8114620009ec57600080fd5b50565b620009fa81620008b2565b811462000a0657600080fd5b50565b6116e08062000a196000396000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c80639c7ec881116100715780639c7ec8811461017f578063a1c130d41461019d578063a43564eb146101bb578063a6ace8a3146101eb578063b97dd9e214610209578063f7e251f814610227576100b4565b806305917ac0146100b957806315e5a1e5146100d7578063290e4544146100f557806343312451146101135780634ff0876a14610143578063674247d614610161575b600080fd5b6100c1610257565b6040516100ce9190611261565b60405180910390f35b6100df61025c565b6040516100ec9190611261565b60405180910390f35b6100fd610262565b60405161010a9190611261565b60405180910390f35b61012d60048036038101906101289190610f39565b610546565b60405161013a9190611261565b60405180910390f35b61014b61055a565b6040516101589190611261565b60405180910390f35b610169610560565b6040516101769190611261565b60405180910390f35b610187610568565b6040516101949190611246565b60405180910390f35b6101a561058a565b6040516101b29190611261565b60405180910390f35b6101d560048036038101906101d09190610f9e565b6105ff565b6040516101e29190611261565b60405180910390f35b6101f3610931565b6040516102009190611246565b60405180910390f35b610211610936565b60405161021e9190611261565b60405180910390f35b610241600480360381019061023c9190610f9e565b610957565b60405161024e9190611261565b60405180910390f35b602881565b60095481565b60008060006102946001610274610995565b6fffffffffffffffffffffffffffffffff166109ec90919063ffffffff16565b905060288111156102a457602890505b60006001600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a90046fffffffffffffffffffffffffffffffff1661030e91906112b6565b90505b81816fffffffffffffffffffffffffffffffff16116103535761033381610a02565b8361033e91906112fc565b9250808061034b90611475565b915050610311565b503373ffffffffffffffffffffffffffffffffffffffff167fb68dafc1da13dc868096d0b87347c831d0bda92d178317eb1dec7f788444485c600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff168361040591906113dd565b8460405161041492919061127c565b60405180910390a2600082111561053e576000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1633866040518463ffffffff1660e01b81526004016104a893929190611126565b602060405180830381600087803b1580156104c257600080fd5b505af11580156104d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104fa9190610f75565b90508061053c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161053390611206565b60405180910390fd5b505b819250505090565b60006105528383610bc4565b905092915050565b60085481565b63042c1d8081565b600660009054906101000a90046fffffffffffffffffffffffffffffffff1681565b6000600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16905090565b6000816fffffffffffffffffffffffffffffffff1661061c610995565b6fffffffffffffffffffffffffffffffff161161066e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161066590611226565b60405180910390fd5b6028826fffffffffffffffffffffffffffffffff1611156106c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106bb90611186565b60405180910390fd5b816fffffffffffffffffffffffffffffffff166107586001600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16610ca590919063ffffffff16565b14610798576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161078f906111c6565b60405180910390fd5b60006107a383610a02565b905060008111156108c7576000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1633856040518463ffffffff1660e01b815260040161083193929190611126565b602060405180830381600087803b15801561084b57600080fd5b505af115801561085f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108839190610f75565b9050806108c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108bc906111e6565b60405180910390fd5b505b826fffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f04ad45a69eeed9c390c3a678fed2d4b90bde98e742de9936d5e0915bf3d0ea4e836040516109209190611261565b60405180910390a380915050919050565b601981565b6000610940610995565b6fffffffffffffffffffffffffffffffff16905090565b600061096282610cbb565b9050919050565b600081836109779190611383565b905092915050565b6000818361098d9190611352565b905092915050565b60006009544210156109aa57600090506109e9565b6109e660016109d86008546109ca600954426109ec90919063ffffffff16565b61097f90919063ffffffff16565b610ca590919063ffffffff16565b90505b90565b600081836109fa91906113dd565b905092915050565b6000816fffffffffffffffffffffffffffffffff16600660009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff161015610a5857610a5782610d99565b5b81600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060006004836fffffffffffffffffffffffffffffffff1681548110610b1c577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001541415610b365760009050610bbf565b610bbc6004836fffffffffffffffffffffffffffffffff1681548110610b85577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154610bae610b9d3386610bc4565b60055461096990919063ffffffff16565b61097f90919063ffffffff16565b90505b919050565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638c028dd08460008054906101000a900473ffffffffffffffffffffffffffffffffffffffff16610c2f86610ecf565b6040518463ffffffff1660e01b8152600401610c4d939291906110ef565b60206040518083038186803b158015610c6557600080fd5b505afa158015610c79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c9d9190610fc7565b905092915050565b60008183610cb391906112fc565b905092915050565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632ca32d7e60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff16610d2585610ecf565b6040518363ffffffff1660e01b8152600401610d4292919061115d565b60206040518083038186803b158015610d5a57600080fd5b505afa158015610d6e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d929190610fc7565b9050919050565b806fffffffffffffffffffffffffffffffff16610df06001600660009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16610ca590919063ffffffff16565b14610e30576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e27906111a6565b60405180910390fd5b80600660006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550610e7281610cbb565b6004826fffffffffffffffffffffffffffffffff1681548110610ebe577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020018190555050565b6000601982610ede91906112b6565b9050919050565b600081359050610ef48161164e565b92915050565b600081519050610f0981611665565b92915050565b600081359050610f1e8161167c565b92915050565b600081519050610f3381611693565b92915050565b60008060408385031215610f4c57600080fd5b6000610f5a85828601610ee5565b9250506020610f6b85828601610f0f565b9150509250929050565b600060208284031215610f8757600080fd5b6000610f9584828501610efa565b91505092915050565b600060208284031215610fb057600080fd5b6000610fbe84828501610f0f565b91505092915050565b600060208284031215610fd957600080fd5b6000610fe784828501610f24565b91505092915050565b610ff981611411565b82525050565b600061100c601e836112a5565b91506110178261150c565b602082019050919050565b600061102f601f836112a5565b915061103a82611535565b602082019050919050565b60006110526010836112a5565b915061105d8261155e565b602082019050919050565b60006110756021836112a5565b915061108082611587565b604082019050919050565b60006110986026836112a5565b91506110a3826115d6565b604082019050919050565b60006110bb601b836112a5565b91506110c682611625565b602082019050919050565b6110da8161142f565b82525050565b6110e98161146b565b82525050565b60006060820190506111046000830186610ff0565b6111116020830185610ff0565b61111e60408301846110d1565b949350505050565b600060608201905061113b6000830186610ff0565b6111486020830185610ff0565b61115560408301846110e0565b949350505050565b60006040820190506111726000830185610ff0565b61117f60208301846110d1565b9392505050565b6000602082019050818103600083015261119f81610fff565b9050919050565b600060208201905081810360008301526111bf81611022565b9050919050565b600060208201905081810360008301526111df81611045565b9050919050565b600060208201905081810360008301526111ff81611068565b9050919050565b6000602082019050818103600083015261121f8161108b565b9050919050565b6000602082019050818103600083015261123f816110ae565b9050919050565b600060208201905061125b60008301846110d1565b92915050565b600060208201905061127660008301846110e0565b92915050565b600060408201905061129160008301856110e0565b61129e60208301846110e0565b9392505050565b600082825260208201905092915050565b60006112c18261142f565b91506112cc8361142f565b9250826fffffffffffffffffffffffffffffffff038211156112f1576112f06114ae565b5b828201905092915050565b60006113078261146b565b91506113128361146b565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115611347576113466114ae565b5b828201905092915050565b600061135d8261146b565b91506113688361146b565b925082611378576113776114dd565b5b828204905092915050565b600061138e8261146b565b91506113998361146b565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156113d2576113d16114ae565b5b828202905092915050565b60006113e88261146b565b91506113f38361146b565b925082821015611406576114056114ae565b5b828203905092915050565b600061141c8261144b565b9050919050565b60008115159050919050565b60006fffffffffffffffffffffffffffffffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60006114808261142f565b91506fffffffffffffffffffffffffffffffff8214156114a3576114a26114ae565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4d6178696d756d206e756d626572206f662065706f6368732069732031320000600082015250565b7f45706f63682063616e20626520696e6974206f6e6c7920696e206f7264657200600082015250565b7f4861727665737420696e206f7264657200000000000000000000000000000000600082015250565b7f4661696c656420746f207472616e73666572206861727665737420726577617260008201527f6400000000000000000000000000000000000000000000000000000000000000602082015250565b7f4661696c656420746f207472616e73666572206d61737320686172766573742060008201527f7265776172640000000000000000000000000000000000000000000000000000602082015250565b7f546869732065706f636820697320696e20746865206675747572650000000000600082015250565b61165781611411565b811461166257600080fd5b50565b61166e81611423565b811461167957600080fd5b50565b6116858161142f565b811461169057600080fd5b50565b61169c8161146b565b81146116a757600080fd5b5056fea2646970667358221220549a24f6edd36c8499239efc2929507e2a00e8c5138387f4da345d7dc0dcb22664736f6c63430008040033000000000000000000000000f293d23bf2cdc05411ca0eddd588eb1977e8dcd40000000000000000000000002a66392317698c5818df7a72a58556049f0ae6f2000000000000000000000000f52ca8c3812ba6b0d820deba852ae781a39fefe700000000000000000000000087eb64e695f1a40a8e86a0cc605a263475221960
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100b45760003560e01c80639c7ec881116100715780639c7ec8811461017f578063a1c130d41461019d578063a43564eb146101bb578063a6ace8a3146101eb578063b97dd9e214610209578063f7e251f814610227576100b4565b806305917ac0146100b957806315e5a1e5146100d7578063290e4544146100f557806343312451146101135780634ff0876a14610143578063674247d614610161575b600080fd5b6100c1610257565b6040516100ce9190611261565b60405180910390f35b6100df61025c565b6040516100ec9190611261565b60405180910390f35b6100fd610262565b60405161010a9190611261565b60405180910390f35b61012d60048036038101906101289190610f39565b610546565b60405161013a9190611261565b60405180910390f35b61014b61055a565b6040516101589190611261565b60405180910390f35b610169610560565b6040516101769190611261565b60405180910390f35b610187610568565b6040516101949190611246565b60405180910390f35b6101a561058a565b6040516101b29190611261565b60405180910390f35b6101d560048036038101906101d09190610f9e565b6105ff565b6040516101e29190611261565b60405180910390f35b6101f3610931565b6040516102009190611246565b60405180910390f35b610211610936565b60405161021e9190611261565b60405180910390f35b610241600480360381019061023c9190610f9e565b610957565b60405161024e9190611261565b60405180910390f35b602881565b60095481565b60008060006102946001610274610995565b6fffffffffffffffffffffffffffffffff166109ec90919063ffffffff16565b905060288111156102a457602890505b60006001600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a90046fffffffffffffffffffffffffffffffff1661030e91906112b6565b90505b81816fffffffffffffffffffffffffffffffff16116103535761033381610a02565b8361033e91906112fc565b9250808061034b90611475565b915050610311565b503373ffffffffffffffffffffffffffffffffffffffff167fb68dafc1da13dc868096d0b87347c831d0bda92d178317eb1dec7f788444485c600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff168361040591906113dd565b8460405161041492919061127c565b60405180910390a2600082111561053e576000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1633866040518463ffffffff1660e01b81526004016104a893929190611126565b602060405180830381600087803b1580156104c257600080fd5b505af11580156104d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104fa9190610f75565b90508061053c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161053390611206565b60405180910390fd5b505b819250505090565b60006105528383610bc4565b905092915050565b60085481565b63042c1d8081565b600660009054906101000a90046fffffffffffffffffffffffffffffffff1681565b6000600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16905090565b6000816fffffffffffffffffffffffffffffffff1661061c610995565b6fffffffffffffffffffffffffffffffff161161066e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161066590611226565b60405180910390fd5b6028826fffffffffffffffffffffffffffffffff1611156106c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106bb90611186565b60405180910390fd5b816fffffffffffffffffffffffffffffffff166107586001600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16610ca590919063ffffffff16565b14610798576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161078f906111c6565b60405180910390fd5b60006107a383610a02565b905060008111156108c7576000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1633856040518463ffffffff1660e01b815260040161083193929190611126565b602060405180830381600087803b15801561084b57600080fd5b505af115801561085f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108839190610f75565b9050806108c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108bc906111e6565b60405180910390fd5b505b826fffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f04ad45a69eeed9c390c3a678fed2d4b90bde98e742de9936d5e0915bf3d0ea4e836040516109209190611261565b60405180910390a380915050919050565b601981565b6000610940610995565b6fffffffffffffffffffffffffffffffff16905090565b600061096282610cbb565b9050919050565b600081836109779190611383565b905092915050565b6000818361098d9190611352565b905092915050565b60006009544210156109aa57600090506109e9565b6109e660016109d86008546109ca600954426109ec90919063ffffffff16565b61097f90919063ffffffff16565b610ca590919063ffffffff16565b90505b90565b600081836109fa91906113dd565b905092915050565b6000816fffffffffffffffffffffffffffffffff16600660009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff161015610a5857610a5782610d99565b5b81600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060006004836fffffffffffffffffffffffffffffffff1681548110610b1c577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001541415610b365760009050610bbf565b610bbc6004836fffffffffffffffffffffffffffffffff1681548110610b85577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154610bae610b9d3386610bc4565b60055461096990919063ffffffff16565b61097f90919063ffffffff16565b90505b919050565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638c028dd08460008054906101000a900473ffffffffffffffffffffffffffffffffffffffff16610c2f86610ecf565b6040518463ffffffff1660e01b8152600401610c4d939291906110ef565b60206040518083038186803b158015610c6557600080fd5b505afa158015610c79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c9d9190610fc7565b905092915050565b60008183610cb391906112fc565b905092915050565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632ca32d7e60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff16610d2585610ecf565b6040518363ffffffff1660e01b8152600401610d4292919061115d565b60206040518083038186803b158015610d5a57600080fd5b505afa158015610d6e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d929190610fc7565b9050919050565b806fffffffffffffffffffffffffffffffff16610df06001600660009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16610ca590919063ffffffff16565b14610e30576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e27906111a6565b60405180910390fd5b80600660006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550610e7281610cbb565b6004826fffffffffffffffffffffffffffffffff1681548110610ebe577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020018190555050565b6000601982610ede91906112b6565b9050919050565b600081359050610ef48161164e565b92915050565b600081519050610f0981611665565b92915050565b600081359050610f1e8161167c565b92915050565b600081519050610f3381611693565b92915050565b60008060408385031215610f4c57600080fd5b6000610f5a85828601610ee5565b9250506020610f6b85828601610f0f565b9150509250929050565b600060208284031215610f8757600080fd5b6000610f9584828501610efa565b91505092915050565b600060208284031215610fb057600080fd5b6000610fbe84828501610f0f565b91505092915050565b600060208284031215610fd957600080fd5b6000610fe784828501610f24565b91505092915050565b610ff981611411565b82525050565b600061100c601e836112a5565b91506110178261150c565b602082019050919050565b600061102f601f836112a5565b915061103a82611535565b602082019050919050565b60006110526010836112a5565b915061105d8261155e565b602082019050919050565b60006110756021836112a5565b915061108082611587565b604082019050919050565b60006110986026836112a5565b91506110a3826115d6565b604082019050919050565b60006110bb601b836112a5565b91506110c682611625565b602082019050919050565b6110da8161142f565b82525050565b6110e98161146b565b82525050565b60006060820190506111046000830186610ff0565b6111116020830185610ff0565b61111e60408301846110d1565b949350505050565b600060608201905061113b6000830186610ff0565b6111486020830185610ff0565b61115560408301846110e0565b949350505050565b60006040820190506111726000830185610ff0565b61117f60208301846110d1565b9392505050565b6000602082019050818103600083015261119f81610fff565b9050919050565b600060208201905081810360008301526111bf81611022565b9050919050565b600060208201905081810360008301526111df81611045565b9050919050565b600060208201905081810360008301526111ff81611068565b9050919050565b6000602082019050818103600083015261121f8161108b565b9050919050565b6000602082019050818103600083015261123f816110ae565b9050919050565b600060208201905061125b60008301846110d1565b92915050565b600060208201905061127660008301846110e0565b92915050565b600060408201905061129160008301856110e0565b61129e60208301846110e0565b9392505050565b600082825260208201905092915050565b60006112c18261142f565b91506112cc8361142f565b9250826fffffffffffffffffffffffffffffffff038211156112f1576112f06114ae565b5b828201905092915050565b60006113078261146b565b91506113128361146b565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115611347576113466114ae565b5b828201905092915050565b600061135d8261146b565b91506113688361146b565b925082611378576113776114dd565b5b828204905092915050565b600061138e8261146b565b91506113998361146b565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156113d2576113d16114ae565b5b828202905092915050565b60006113e88261146b565b91506113f38361146b565b925082821015611406576114056114ae565b5b828203905092915050565b600061141c8261144b565b9050919050565b60008115159050919050565b60006fffffffffffffffffffffffffffffffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60006114808261142f565b91506fffffffffffffffffffffffffffffffff8214156114a3576114a26114ae565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4d6178696d756d206e756d626572206f662065706f6368732069732031320000600082015250565b7f45706f63682063616e20626520696e6974206f6e6c7920696e206f7264657200600082015250565b7f4861727665737420696e206f7264657200000000000000000000000000000000600082015250565b7f4661696c656420746f207472616e73666572206861727665737420726577617260008201527f6400000000000000000000000000000000000000000000000000000000000000602082015250565b7f4661696c656420746f207472616e73666572206d61737320686172766573742060008201527f7265776172640000000000000000000000000000000000000000000000000000602082015250565b7f546869732065706f636820697320696e20746865206675747572650000000000600082015250565b61165781611411565b811461166257600080fd5b50565b61166e81611423565b811461167957600080fd5b50565b6116858161142f565b811461169057600080fd5b50565b61169c8161146b565b81146116a757600080fd5b5056fea2646970667358221220549a24f6edd36c8499239efc2929507e2a00e8c5138387f4da345d7dc0dcb22664736f6c63430008040033
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.