Contract Overview
Contract Name:
SolarDistributorV2
Compiler Version
v0.8.9+commit.e5eed63a
// Sources flattened with hardhat v2.6.0 https://hardhat.org // File @openzeppelin/contracts/utils/[email protected] // SPDX-License-Identifier: MIT 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; } } // File @openzeppelin/contracts/access/[email protected] pragma solidity ^0.8.0; /** * @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() { _setOwner(_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 { _setOwner(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"); _setOwner(newOwner); } function _setOwner(address newOwner) private { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // File @openzeppelin/contracts/security/[email protected] 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 make 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; } } // File @openzeppelin/contracts/utils/[email protected] pragma solidity ^0.8.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) private pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // File contracts/farm/v2/libraries/IBoringERC20.sol pragma solidity ^0.8.7; interface IBoringERC20 { function mint(address to, uint256 amount) external; function totalSupply() external view returns (uint256); function balanceOf(address account) external view returns (uint256); function allowance(address owner, address spender) external view returns (uint256); function approve(address spender, uint256 amount) external returns (bool); event Transfer(address indexed from, address indexed to, uint256 value); event Approval( address indexed owner, address indexed spender, uint256 value ); /// @notice EIP 2612 function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; } // File contracts/farm/v2/rewarders/IComplexRewarder.sol pragma solidity ^0.8.7; interface IComplexRewarder { function onSolarReward( uint256 pid, address user, uint256 newLpAmount ) external; function pendingTokens(uint256 pid, address user) external view returns (uint256 pending); function rewardToken() external view returns (IBoringERC20); function poolRewardsPerSec(uint256 pid) external view returns (uint256); } // File contracts/farm/v2/libraries/BoringERC20.sol pragma solidity ^0.8.7; // solhint-disable avoid-low-level-calls library BoringERC20 { bytes4 private constant SIG_SYMBOL = 0x95d89b41; // symbol() bytes4 private constant SIG_NAME = 0x06fdde03; // name() bytes4 private constant SIG_DECIMALS = 0x313ce567; // decimals() bytes4 private constant SIG_TRANSFER = 0xa9059cbb; // transfer(address,uint256) bytes4 private constant SIG_TRANSFER_FROM = 0x23b872dd; // transferFrom(address,address,uint256) function returnDataToString(bytes memory data) internal pure returns (string memory) { if (data.length >= 64) { return abi.decode(data, (string)); } else if (data.length == 32) { uint8 i = 0; while (i < 32 && data[i] != 0) { i++; } bytes memory bytesArray = new bytes(i); for (i = 0; i < 32 && data[i] != 0; i++) { bytesArray[i] = data[i]; } return string(bytesArray); } else { return "???"; } } /// @notice Provides a safe ERC20.symbol version which returns '???' as fallback string. /// @param token The address of the ERC-20 token contract. /// @return (string) Token symbol. function safeSymbol(IBoringERC20 token) internal view returns (string memory) { (bool success, bytes memory data) = address(token).staticcall( abi.encodeWithSelector(SIG_SYMBOL) ); return success ? returnDataToString(data) : "???"; } /// @notice Provides a safe ERC20.name version which returns '???' as fallback string. /// @param token The address of the ERC-20 token contract. /// @return (string) Token name. function safeName(IBoringERC20 token) internal view returns (string memory) { (bool success, bytes memory data) = address(token).staticcall( abi.encodeWithSelector(SIG_NAME) ); return success ? returnDataToString(data) : "???"; } /// @notice Provides a safe ERC20.decimals version which returns '18' as fallback value. /// @param token The address of the ERC-20 token contract. /// @return (uint8) Token decimals. function safeDecimals(IBoringERC20 token) internal view returns (uint8) { (bool success, bytes memory data) = address(token).staticcall( abi.encodeWithSelector(SIG_DECIMALS) ); return success && data.length == 32 ? abi.decode(data, (uint8)) : 18; } /// @notice Provides a safe ERC20.transfer version for different ERC-20 implementations. /// Reverts on a failed transfer. /// @param token The address of the ERC-20 token. /// @param to Transfer tokens to. /// @param amount The token amount. function safeTransfer( IBoringERC20 token, address to, uint256 amount ) internal { (bool success, bytes memory data) = address(token).call( abi.encodeWithSelector(SIG_TRANSFER, to, amount) ); require( success && (data.length == 0 || abi.decode(data, (bool))), "BoringERC20: Transfer failed" ); } /// @notice Provides a safe ERC20.transferFrom version for different ERC-20 implementations. /// Reverts on a failed transfer. /// @param token The address of the ERC-20 token. /// @param from Transfer tokens from. /// @param to Transfer tokens to. /// @param amount The token amount. function safeTransferFrom( IBoringERC20 token, address from, address to, uint256 amount ) internal { (bool success, bytes memory data) = address(token).call( abi.encodeWithSelector(SIG_TRANSFER_FROM, from, to, amount) ); require( success && (data.length == 0 || abi.decode(data, (bool))), "BoringERC20: TransferFrom failed" ); } } // File contracts/farm/v2/ISolarPair.sol pragma solidity ^0.8.7; interface ISolarPair { function initialize(address, address) external; function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; } // File contracts/farm/v2/SolarDistributorV2.sol pragma solidity ^0.8.7; contract SolarDistributorV2 is Ownable, ReentrancyGuard { using BoringERC20 for IBoringERC20; // Info of each user. struct UserInfo { uint256 amount; // How many LP tokens the user has provided. uint256 rewardDebt; // Reward debt. See explanation below. uint256 rewardLockedUp; // Reward locked up. uint256 nextHarvestUntil; // When can the user harvest again. } // Info of each pool. struct PoolInfo { IBoringERC20 lpToken; // Address of LP token contract. uint256 allocPoint; // How many allocation points assigned to this pool. Solar to distribute per block. uint256 lastRewardTimestamp; // Last block number that Solar distribution occurs. uint256 accSolarPerShare; // Accumulated Solar per share, times 1e18. See below. uint16 depositFeeBP; // Deposit fee in basis points uint256 harvestInterval; // Harvest interval in seconds uint256 totalLp; // Total token in Pool IComplexRewarder[] rewarders; // Array of rewarder contract for pools with incentives } IBoringERC20 public solar; // Solar tokens created per second uint256 public solarPerSec; // Max harvest interval: 14 days uint256 public constant MAXIMUM_HARVEST_INTERVAL = 14 days; // Maximum deposit fee rate: 10% uint16 public constant MAXIMUM_DEPOSIT_FEE_RATE = 1000; // Info of each pool PoolInfo[] public poolInfo; // Info of each user that stakes LP tokens. mapping(uint256 => mapping(address => UserInfo)) public userInfo; // Total allocation points. Must be the sum of all allocation points in all pools. uint256 public totalAllocPoint = 0; // The timestamp when Solar mining starts. uint256 public startTimestamp; // Total locked up rewards uint256 public totalLockedUpRewards; // Total Solar in Solar Pools (can be multiple pools) uint256 public totalSolarInPools = 0; // Team address. address public teamAddress; // Treasury address. address public treasuryAddress; // Investor address. address public investorAddress; // Percentage of pool rewards that goto the team. uint256 public teamPercent; // Percentage of pool rewards that goes to the treasury. uint256 public treasuryPercent; // Percentage of pool rewards that goes to the investor. uint256 public investorPercent; // The precision factor uint256 private immutable ACC_TOKEN_PRECISION = 1e12; modifier validatePoolByPid(uint256 _pid) { require(_pid < poolInfo.length, "Pool does not exist"); _; } event Add( uint256 indexed pid, uint256 allocPoint, IBoringERC20 indexed lpToken, uint16 depositFeeBP, uint256 harvestInterval, IComplexRewarder[] indexed rewarders ); event Set( uint256 indexed pid, uint256 allocPoint, uint16 depositFeeBP, uint256 harvestInterval, IComplexRewarder[] indexed rewarders ); event UpdatePool( uint256 indexed pid, uint256 lastRewardTimestamp, uint256 lpSupply, uint256 accSolarPerShare ); event Deposit(address indexed user, uint256 indexed pid, uint256 amount); event Withdraw(address indexed user, uint256 indexed pid, uint256 amount); event EmergencyWithdraw( address indexed user, uint256 indexed pid, uint256 amount ); event EmissionRateUpdated( address indexed caller, uint256 previousValue, uint256 newValue ); event RewardLockedUp( address indexed user, uint256 indexed pid, uint256 amountLockedUp ); event AllocPointsUpdated( address indexed caller, uint256 previousAmount, uint256 newAmount ); event SetTeamAddress( address indexed oldAddress, address indexed newAddress ); event SetTreasuryAddress( address indexed oldAddress, address indexed newAddress ); event SetInvestorAddress( address indexed oldAddress, address indexed newAddress ); event SetTeamPercent(uint256 oldPercent, uint256 newPercent); event SetTreasuryPercent(uint256 oldPercent, uint256 newPercent); event SetInvestorPercent(uint256 oldPercent, uint256 newPercent); constructor( IBoringERC20 _solar, uint256 _solarPerSec, address _teamAddress, address _treasuryAddress, address _investorAddress, uint256 _teamPercent, uint256 _treasuryPercent, uint256 _investorPercent ) { require( 0 <= _teamPercent && _teamPercent <= 1000, "constructor: invalid team percent value" ); require( 0 <= _treasuryPercent && _treasuryPercent <= 1000, "constructor: invalid treasury percent value" ); require( 0 <= _investorPercent && _investorPercent <= 1000, "constructor: invalid investor percent value" ); require( _teamPercent + _treasuryPercent + _investorPercent <= 1000, "constructor: total percent over max" ); //StartBlock always many years later from contract const ruct, will be set later in StartFarming function startTimestamp = block.timestamp + (60 * 60 * 24 * 365); solar = _solar; solarPerSec = _solarPerSec; teamAddress = _teamAddress; treasuryAddress = _treasuryAddress; investorAddress = _investorAddress; teamPercent = _teamPercent; treasuryPercent = _treasuryPercent; investorPercent = _investorPercent; } // Set farming start, can call only once function startFarming() public onlyOwner { require( block.timestamp < startTimestamp, "start farming: farm started already" ); uint256 length = poolInfo.length; for (uint256 pid = 0; pid < length; ++pid) { PoolInfo storage pool = poolInfo[pid]; pool.lastRewardTimestamp = block.timestamp; } startTimestamp = block.timestamp; } function poolLength() external view returns (uint256) { return poolInfo.length; } // Add a new lp to the pool. Can only be called by the owner. // Can add multiple pool with same lp token without messing up rewards, because each pool's balance is tracked using its own totalLp function add( uint256 _allocPoint, IBoringERC20 _lpToken, uint16 _depositFeeBP, uint256 _harvestInterval, IComplexRewarder[] calldata _rewarders ) public onlyOwner { require(_rewarders.length <= 10, "add: too many rewarders"); require( _depositFeeBP <= MAXIMUM_DEPOSIT_FEE_RATE, "add: deposit fee too high" ); require( _harvestInterval <= MAXIMUM_HARVEST_INTERVAL, "add: invalid harvest interval" ); require( Address.isContract(address(_lpToken)), "add: LP token must be a valid contract" ); for ( uint256 rewarderId = 0; rewarderId < _rewarders.length; ++rewarderId ) { require( Address.isContract(address(_rewarders[rewarderId])), "add: rewarder must be contract" ); } _massUpdatePools(); uint256 lastRewardTimestamp = block.timestamp > startTimestamp ? block.timestamp : startTimestamp; totalAllocPoint += _allocPoint; poolInfo.push( PoolInfo({ lpToken: _lpToken, allocPoint: _allocPoint, lastRewardTimestamp: lastRewardTimestamp, accSolarPerShare: 0, depositFeeBP: _depositFeeBP, harvestInterval: _harvestInterval, totalLp: 0, rewarders: _rewarders }) ); emit Add( poolInfo.length - 1, _allocPoint, _lpToken, _depositFeeBP, _harvestInterval, _rewarders ); } // Update the given pool's Solar allocation point and deposit fee. Can only be called by the owner. function set( uint256 _pid, uint256 _allocPoint, uint16 _depositFeeBP, uint256 _harvestInterval, IComplexRewarder[] calldata _rewarders ) public onlyOwner validatePoolByPid(_pid) { require(_rewarders.length <= 10, "set: too many rewarders"); require( _depositFeeBP <= MAXIMUM_DEPOSIT_FEE_RATE, "set: deposit fee too high" ); require( _harvestInterval <= MAXIMUM_HARVEST_INTERVAL, "set: invalid harvest interval" ); for ( uint256 rewarderId = 0; rewarderId < _rewarders.length; ++rewarderId ) { require( Address.isContract(address(_rewarders[rewarderId])), "add: rewarder must be contract" ); } _massUpdatePools(); totalAllocPoint = totalAllocPoint - poolInfo[_pid].allocPoint + _allocPoint; poolInfo[_pid].allocPoint = _allocPoint; poolInfo[_pid].depositFeeBP = _depositFeeBP; poolInfo[_pid].harvestInterval = _harvestInterval; poolInfo[_pid].rewarders = _rewarders; emit Set( _pid, _allocPoint, _depositFeeBP, _harvestInterval, _rewarders ); } // View function to see pending rewards on frontend. function pendingTokens(uint256 _pid, address _user) external view validatePoolByPid(_pid) returns ( address[] memory addresses, string[] memory symbols, uint256[] memory decimals, uint256[] memory amounts ) { PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][_user]; uint256 accSolarPerShare = pool.accSolarPerShare; uint256 lpSupply = pool.totalLp; if (block.timestamp > pool.lastRewardTimestamp && lpSupply != 0) { uint256 multiplier = block.timestamp - pool.lastRewardTimestamp; uint256 lpPercent = 1000 - teamPercent - treasuryPercent - investorPercent; uint256 solarReward = ((((multiplier * solarPerSec) * pool.allocPoint) / totalAllocPoint) * lpPercent) / 1000; accSolarPerShare += ( ((solarReward * ACC_TOKEN_PRECISION) / lpSupply) ); } uint256 pendingSolar = (((user.amount * accSolarPerShare) / ACC_TOKEN_PRECISION) - user.rewardDebt) + user.rewardLockedUp; addresses = new address[](pool.rewarders.length + 1); symbols = new string[](pool.rewarders.length + 1); amounts = new uint256[](pool.rewarders.length + 1); decimals = new uint256[](pool.rewarders.length + 1); addresses[0] = address(solar); symbols[0] = IBoringERC20(solar).safeSymbol(); decimals[0] = IBoringERC20(solar).safeDecimals(); amounts[0] = pendingSolar; for ( uint256 rewarderId = 0; rewarderId < pool.rewarders.length; ++rewarderId ) { addresses[rewarderId + 1] = address( pool.rewarders[rewarderId].rewardToken() ); symbols[rewarderId + 1] = IBoringERC20( pool.rewarders[rewarderId].rewardToken() ).safeSymbol(); decimals[rewarderId + 1] = IBoringERC20( pool.rewarders[rewarderId].rewardToken() ).safeDecimals(); amounts[rewarderId + 1] = pool.rewarders[rewarderId].pendingTokens( _pid, _user ); } } /// @notice View function to see pool rewards per sec function poolRewardsPerSec(uint256 _pid) external view validatePoolByPid(_pid) returns ( address[] memory addresses, string[] memory symbols, uint256[] memory decimals, uint256[] memory rewardsPerSec ) { PoolInfo storage pool = poolInfo[_pid]; addresses = new address[](pool.rewarders.length + 1); symbols = new string[](pool.rewarders.length + 1); decimals = new uint256[](pool.rewarders.length + 1); rewardsPerSec = new uint256[](pool.rewarders.length + 1); addresses[0] = address(solar); symbols[0] = IBoringERC20(solar).safeSymbol(); decimals[0] = IBoringERC20(solar).safeDecimals(); rewardsPerSec[0] = (pool.allocPoint * solarPerSec) / totalAllocPoint; for ( uint256 rewarderId = 0; rewarderId < pool.rewarders.length; ++rewarderId ) { addresses[rewarderId + 1] = address( pool.rewarders[rewarderId].rewardToken() ); symbols[rewarderId + 1] = IBoringERC20( pool.rewarders[rewarderId].rewardToken() ).safeSymbol(); decimals[rewarderId + 1] = IBoringERC20( pool.rewarders[rewarderId].rewardToken() ).safeDecimals(); rewardsPerSec[rewarderId + 1] = pool .rewarders[rewarderId] .poolRewardsPerSec(_pid); } } // View function to see rewarders for a pool function poolRewarders(uint256 _pid) external view validatePoolByPid(_pid) returns (address[] memory rewarders) { PoolInfo storage pool = poolInfo[_pid]; for ( uint256 rewarderId = 0; rewarderId < pool.rewarders.length; ++rewarderId ) { rewarders[rewarderId] = address(pool.rewarders[rewarderId]); } } // View function to see if user can harvest Solar. function canHarvest(uint256 _pid, address _user) public view validatePoolByPid(_pid) returns (bool) { UserInfo storage user = userInfo[_pid][_user]; return block.timestamp >= startTimestamp && block.timestamp >= user.nextHarvestUntil; } // Update reward vairables for all pools. Be careful of gas spending! function massUpdatePools() external nonReentrant { _massUpdatePools(); } // Internal method for massUpdatePools function _massUpdatePools() internal { for (uint256 pid = 0; pid < poolInfo.length; ++pid) { _updatePool(pid); } } // Update reward variables of the given pool to be up-to-date. function updatePool(uint256 _pid) external nonReentrant { _updatePool(_pid); } // Internal method for _updatePool function _updatePool(uint256 _pid) internal validatePoolByPid(_pid) { PoolInfo storage pool = poolInfo[_pid]; if (block.timestamp <= pool.lastRewardTimestamp) { return; } uint256 lpSupply = pool.totalLp; if (lpSupply == 0 || pool.allocPoint == 0) { pool.lastRewardTimestamp = block.timestamp; return; } uint256 multiplier = block.timestamp - pool.lastRewardTimestamp; uint256 solarReward = ((multiplier * solarPerSec) * pool.allocPoint) / totalAllocPoint; uint256 lpPercent = 1000 - teamPercent - treasuryPercent - investorPercent; solar.mint(teamAddress, (solarReward * teamPercent) / 1000); solar.mint(treasuryAddress, (solarReward * treasuryPercent) / 1000); solar.mint(investorAddress, (solarReward * investorPercent) / 1000); solar.mint(address(this), (solarReward * lpPercent) / 1000); pool.accSolarPerShare += (((solarReward * ACC_TOKEN_PRECISION) / pool.totalLp) * lpPercent) / 1000; pool.lastRewardTimestamp = block.timestamp; emit UpdatePool( _pid, pool.lastRewardTimestamp, lpSupply, pool.accSolarPerShare ); } function depositWithPermit( uint256 pid, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) public nonReentrant validatePoolByPid(pid) { PoolInfo storage pool = poolInfo[pid]; ISolarPair pair = ISolarPair(address(pool.lpToken)); pair.permit(msg.sender, address(this), amount, deadline, v, r, s); _deposit(pid, amount); } // Deposit tokens for Solar allocation. function deposit(uint256 _pid, uint256 _amount) public nonReentrant { _deposit(_pid, _amount); } // Deposit tokens for Solar allocation. function _deposit(uint256 _pid, uint256 _amount) internal validatePoolByPid(_pid) { PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][msg.sender]; _updatePool(_pid); payOrLockupPendingSolar(_pid); if (_amount > 0) { uint256 beforeDeposit = pool.lpToken.balanceOf(address(this)); pool.lpToken.safeTransferFrom(msg.sender, address(this), _amount); uint256 afterDeposit = pool.lpToken.balanceOf(address(this)); _amount = afterDeposit - beforeDeposit; if (pool.depositFeeBP > 0) { uint256 depositFee = (_amount * pool.depositFeeBP) / 10000; pool.lpToken.safeTransfer(treasuryAddress, depositFee); _amount = _amount - depositFee; } user.amount += _amount; if (address(pool.lpToken) == address(solar)) { totalSolarInPools += _amount; } } user.rewardDebt = (user.amount * pool.accSolarPerShare) / ACC_TOKEN_PRECISION; for ( uint256 rewarderId = 0; rewarderId < pool.rewarders.length; ++rewarderId ) { pool.rewarders[rewarderId].onSolarReward( _pid, msg.sender, user.amount ); } if (_amount > 0) { pool.totalLp += _amount; } emit Deposit(msg.sender, _pid, _amount); } //withdraw tokens function withdraw(uint256 _pid, uint256 _amount) public nonReentrant validatePoolByPid(_pid) { PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][msg.sender]; //this will make sure that user can only withdraw from his pool require(user.amount >= _amount, "withdraw: user amount not enough"); //cannot withdraw more than pool's balance require(pool.totalLp >= _amount, "withdraw: pool total not enough"); _updatePool(_pid); payOrLockupPendingSolar(_pid); if (_amount > 0) { user.amount -= _amount; if (address(pool.lpToken) == address(solar)) { totalSolarInPools -= _amount; } pool.lpToken.safeTransfer(msg.sender, _amount); } user.rewardDebt = (user.amount * pool.accSolarPerShare) / ACC_TOKEN_PRECISION; for ( uint256 rewarderId = 0; rewarderId < pool.rewarders.length; ++rewarderId ) { pool.rewarders[rewarderId].onSolarReward( _pid, msg.sender, user.amount ); } if (_amount > 0) { pool.totalLp -= _amount; } emit Withdraw(msg.sender, _pid, _amount); } // Withdraw without caring about rewards. EMERGENCY ONLY. function emergencyWithdraw(uint256 _pid) public nonReentrant { PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][msg.sender]; uint256 amount = user.amount; //Cannot withdraw more than pool's balance require( pool.totalLp >= amount, "emergency withdraw: pool total not enough" ); user.amount = 0; user.rewardDebt = 0; user.rewardLockedUp = 0; user.nextHarvestUntil = 0; pool.totalLp -= amount; for ( uint256 rewarderId = 0; rewarderId < pool.rewarders.length; ++rewarderId ) { pool.rewarders[rewarderId].onSolarReward(_pid, msg.sender, 0); } if (address(pool.lpToken) == address(solar)) { totalSolarInPools -= amount; } pool.lpToken.safeTransfer(msg.sender, amount); emit EmergencyWithdraw(msg.sender, _pid, amount); } // Pay or lockup pending Solar. function payOrLockupPendingSolar(uint256 _pid) internal { PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][msg.sender]; if (user.nextHarvestUntil == 0 && block.timestamp >= startTimestamp) { user.nextHarvestUntil = block.timestamp + pool.harvestInterval; } uint256 pending = ((user.amount * pool.accSolarPerShare) / ACC_TOKEN_PRECISION) - user.rewardDebt; if (canHarvest(_pid, msg.sender)) { if (pending > 0 || user.rewardLockedUp > 0) { // reset lockup totalLockedUpRewards -= user.rewardLockedUp; user.rewardLockedUp = 0; user.nextHarvestUntil = block.timestamp + pool.harvestInterval; // send rewards safeSolarTransfer(msg.sender, pending + user.rewardLockedUp); } } else if (pending > 0) { totalLockedUpRewards += pending; user.rewardLockedUp += pending; emit RewardLockedUp(msg.sender, _pid, pending); } } // Safe Solar transfer function, just in case if rounding error causes pool do not have enough Solar. function safeSolarTransfer(address _to, uint256 _amount) internal { if (solar.balanceOf(address(this)) > totalSolarInPools) { //solarBal = total Solar in SolarDistributor - total Solar in Solar pools, this will make sure that SolarDistributor never transfer rewards from deposited Solar pools uint256 solarBal = solar.balanceOf(address(this)) - totalSolarInPools; if (_amount >= solarBal) { solar.safeTransfer(_to, solarBal); } else if (_amount > 0) { solar.safeTransfer(_to, _amount); } } } function updateEmissionRate(uint256 _solarPerSec) public onlyOwner { _massUpdatePools(); emit EmissionRateUpdated(msg.sender, solarPerSec, _solarPerSec); solarPerSec = _solarPerSec; } function updateAllocPoint(uint256 _pid, uint256 _allocPoint) public onlyOwner { _massUpdatePools(); emit AllocPointsUpdated( msg.sender, poolInfo[_pid].allocPoint, _allocPoint ); totalAllocPoint = totalAllocPoint - poolInfo[_pid].allocPoint + _allocPoint; poolInfo[_pid].allocPoint = _allocPoint; } function poolTotalLp(uint256 pid) external view returns (uint256) { return poolInfo[pid].totalLp; } // Function to harvest many pools in a single transaction function harvestMany(uint256[] calldata _pids) public nonReentrant { require(_pids.length <= 30, "harvest many: too many pool ids"); for (uint256 index = 0; index < _pids.length; ++index) { // check if pool exists if (index < poolInfo.length) { _deposit(_pids[index], 0); } } } // Update team address by the previous team address. function setTeamAddress(address _teamAddress) public { require( msg.sender == teamAddress, "set team address: only previous team address can call this method" ); teamAddress = _teamAddress; emit SetTeamAddress(msg.sender, _teamAddress); } function setTeamPercent(uint256 _newTeamPercent) public onlyOwner { require( 0 <= _newTeamPercent && _newTeamPercent <= 1000, "set team percent: invalid percent value" ); require( treasuryPercent + _newTeamPercent + investorPercent <= 1000, "set team percent: total percent over max" ); emit SetTeamPercent(teamPercent, _newTeamPercent); teamPercent = _newTeamPercent; } // Update treasury address by the previous treasury. function setTreasuryAddress(address _treasuryAddress) public { require( msg.sender == treasuryAddress, "set treasury address: only previous treasury address can call this method" ); treasuryAddress = _treasuryAddress; emit SetTreasuryAddress(msg.sender, _treasuryAddress); } function setTreasuryPercent(uint256 _newTreasuryPercent) public onlyOwner { require( 0 <= _newTreasuryPercent && _newTreasuryPercent <= 1000, "set treasury percent: invalid percent value" ); require( teamPercent + _newTreasuryPercent + investorPercent <= 1000, "set treasury percent: total percent over max" ); emit SetTeamPercent(treasuryPercent, _newTreasuryPercent); treasuryPercent = _newTreasuryPercent; } // Update the investor address by the previous investor. function setInvestorAddress(address _investorAddress) public { require( msg.sender == investorAddress, "set investor address: only previous investor can call this method" ); investorAddress = _investorAddress; emit SetInvestorAddress(msg.sender, _investorAddress); } function setInvestorPercent(uint256 _newInvestorPercent) public onlyOwner { require( 0 <= _newInvestorPercent && _newInvestorPercent <= 1000, "set investor percent: invalid percent value" ); require( teamPercent + _newInvestorPercent + treasuryPercent <= 1000, "set investor percent: total percent over max" ); emit SetTeamPercent(investorPercent, _newInvestorPercent); investorPercent = _newInvestorPercent; } }
[{"inputs":[{"internalType":"contract IBoringERC20","name":"_solar","type":"address"},{"internalType":"uint256","name":"_solarPerSec","type":"uint256"},{"internalType":"address","name":"_teamAddress","type":"address"},{"internalType":"address","name":"_treasuryAddress","type":"address"},{"internalType":"address","name":"_investorAddress","type":"address"},{"internalType":"uint256","name":"_teamPercent","type":"uint256"},{"internalType":"uint256","name":"_treasuryPercent","type":"uint256"},{"internalType":"uint256","name":"_investorPercent","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"allocPoint","type":"uint256"},{"indexed":true,"internalType":"contract IBoringERC20","name":"lpToken","type":"address"},{"indexed":false,"internalType":"uint16","name":"depositFeeBP","type":"uint16"},{"indexed":false,"internalType":"uint256","name":"harvestInterval","type":"uint256"},{"indexed":true,"internalType":"contract IComplexRewarder[]","name":"rewarders","type":"address[]"}],"name":"Add","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"previousAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newAmount","type":"uint256"}],"name":"AllocPointsUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"EmergencyWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"previousValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"EmissionRateUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountLockedUp","type":"uint256"}],"name":"RewardLockedUp","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"allocPoint","type":"uint256"},{"indexed":false,"internalType":"uint16","name":"depositFeeBP","type":"uint16"},{"indexed":false,"internalType":"uint256","name":"harvestInterval","type":"uint256"},{"indexed":true,"internalType":"contract IComplexRewarder[]","name":"rewarders","type":"address[]"}],"name":"Set","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldAddress","type":"address"},{"indexed":true,"internalType":"address","name":"newAddress","type":"address"}],"name":"SetInvestorAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldPercent","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newPercent","type":"uint256"}],"name":"SetInvestorPercent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldAddress","type":"address"},{"indexed":true,"internalType":"address","name":"newAddress","type":"address"}],"name":"SetTeamAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldPercent","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newPercent","type":"uint256"}],"name":"SetTeamPercent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldAddress","type":"address"},{"indexed":true,"internalType":"address","name":"newAddress","type":"address"}],"name":"SetTreasuryAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldPercent","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newPercent","type":"uint256"}],"name":"SetTreasuryPercent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lastRewardTimestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lpSupply","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"accSolarPerShare","type":"uint256"}],"name":"UpdatePool","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"MAXIMUM_DEPOSIT_FEE_RATE","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAXIMUM_HARVEST_INTERVAL","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_allocPoint","type":"uint256"},{"internalType":"contract IBoringERC20","name":"_lpToken","type":"address"},{"internalType":"uint16","name":"_depositFeeBP","type":"uint16"},{"internalType":"uint256","name":"_harvestInterval","type":"uint256"},{"internalType":"contract IComplexRewarder[]","name":"_rewarders","type":"address[]"}],"name":"add","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_user","type":"address"}],"name":"canHarvest","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pid","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"depositWithPermit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_pids","type":"uint256[]"}],"name":"harvestMany","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"investorAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"investorPercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"massUpdatePools","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_user","type":"address"}],"name":"pendingTokens","outputs":[{"internalType":"address[]","name":"addresses","type":"address[]"},{"internalType":"string[]","name":"symbols","type":"string[]"},{"internalType":"uint256[]","name":"decimals","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"poolInfo","outputs":[{"internalType":"contract IBoringERC20","name":"lpToken","type":"address"},{"internalType":"uint256","name":"allocPoint","type":"uint256"},{"internalType":"uint256","name":"lastRewardTimestamp","type":"uint256"},{"internalType":"uint256","name":"accSolarPerShare","type":"uint256"},{"internalType":"uint16","name":"depositFeeBP","type":"uint16"},{"internalType":"uint256","name":"harvestInterval","type":"uint256"},{"internalType":"uint256","name":"totalLp","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"poolRewarders","outputs":[{"internalType":"address[]","name":"rewarders","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"poolRewardsPerSec","outputs":[{"internalType":"address[]","name":"addresses","type":"address[]"},{"internalType":"string[]","name":"symbols","type":"string[]"},{"internalType":"uint256[]","name":"decimals","type":"uint256[]"},{"internalType":"uint256[]","name":"rewardsPerSec","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pid","type":"uint256"}],"name":"poolTotalLp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_allocPoint","type":"uint256"},{"internalType":"uint16","name":"_depositFeeBP","type":"uint16"},{"internalType":"uint256","name":"_harvestInterval","type":"uint256"},{"internalType":"contract IComplexRewarder[]","name":"_rewarders","type":"address[]"}],"name":"set","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_investorAddress","type":"address"}],"name":"setInvestorAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newInvestorPercent","type":"uint256"}],"name":"setInvestorPercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_teamAddress","type":"address"}],"name":"setTeamAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newTeamPercent","type":"uint256"}],"name":"setTeamPercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_treasuryAddress","type":"address"}],"name":"setTreasuryAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newTreasuryPercent","type":"uint256"}],"name":"setTreasuryPercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"solar","outputs":[{"internalType":"contract IBoringERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"solarPerSec","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"startFarming","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"teamAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"teamPercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAllocPoint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalLockedUpRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSolarInPools","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"treasuryAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"treasuryPercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_allocPoint","type":"uint256"}],"name":"updateAllocPoint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_solarPerSec","type":"uint256"}],"name":"updateEmissionRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"updatePool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"userInfo","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"rewardDebt","type":"uint256"},{"internalType":"uint256","name":"rewardLockedUp","type":"uint256"},{"internalType":"uint256","name":"nextHarvestUntil","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50600436106102695760003560e01c80636690864e11610151578063d761595c116100c3578063e6fa6d6d11610087578063e6fa6d6d14610596578063e6fd48bc146105a9578063eddf9652146105b2578063eff8976b146105c5578063f2fde38b146105e5578063ffcd4263146105f857600080fd5b8063d761595c14610554578063dc640ac91461055d578063de73149d14610570578063e164ac501461057a578063e2bbb1581461058357600080fd5b80638da5cb5b116101155780638da5cb5b146104ac57806393f1a40b146104bd578063949e63021461051d5780639a26c2fa14610530578063afbcfea114610539578063c5f956af1461054157600080fd5b80636690864e1461044f578063715018a614610462578063812c64f11461046a578063876d3c9c1461048657806389a2bc251461049957600080fd5b806342602f1e116101ea578063515bc323116101ae578063515bc323146103e857806351eb05a6146103fb5780635312ea8e1461040e578063630b5ba114610421578063654c9ece146104295780636605bfda1461043c57600080fd5b806342602f1e14610383578063441a3e7014610396578063465e81ec146103a9578063474fa630146103cc578063508593ab146103d557600080fd5b80631526fe27116102315780631526fe27146102db57806317caf6f1146103315780631c75f0851461033a5780632081ccc41461034d5780632e6c998d1461036057600080fd5b806304ef9d581461026e5780630735b2081461028a578063081e3eda146102935780630ba84cd21461029b57806312e228fd146102b0575b600080fd5b610277600e5481565b6040519081526020015b60405180910390f35b610277600f5481565b600454610277565b6102ae6102a9366004613d70565b61060b565b005b600c546102c3906001600160a01b031681565b6040516001600160a01b039091168152602001610281565b6102ee6102e9366004613d70565b610689565b604080516001600160a01b039098168852602088019690965294860193909352606085019190915261ffff16608084015260a083015260c082015260e001610281565b61027760065481565b600a546102c3906001600160a01b031681565b6102ae61035b366004613de6565b6106e6565b61037361036e366004613e6b565b610a3b565b6040519015158152602001610281565b6102ae610391366004613e9b565b610aa2565b6102ae6103a4366004613eb8565b610b78565b6103bc6103b7366004613d70565b610e6c565b6040516102819493929190613f7a565b61027760085481565b6102ae6103e336600461402c565b61144c565b6102ae6103f6366004614074565b611825565b6102ae610409366004613d70565b611938565b6102ae61041c366004613d70565b611970565b6102ae611ba5565b610277610437366004613d70565b611bdb565b6102ae61044a366004613e9b565b611c09565b6102ae61045d366004613e9b565b611ce7565b6102ae611dbd565b6104736103e881565b60405161ffff9091168152602001610281565b6102ae610494366004613d70565b611df3565b6102ae6104a7366004613d70565b611f45565b6000546001600160a01b03166102c3565b6104fd6104cb366004613e6b565b600560209081526000928352604080842090915290825290208054600182015460028301546003909301549192909184565b604080519485526020850193909352918301526060820152608001610281565b6102ae61052b366004613d70565b612097565b61027760035481565b6102ae6121e1565b600b546102c3906001600160a01b031681565b61027760095481565b6102ae61056b3660046140c7565b6122be565b6102776212750081565b610277600d5481565b6102ae610591366004613eb8565b612388565b6002546102c3906001600160a01b031681565b61027760075481565b6102ae6105c0366004613eb8565b6123c2565b6105d86105d3366004613d70565b6124d4565b6040516102819190614108565b6102ae6105f3366004613e9b565b6125a3565b6103bc610606366004613e6b565b61263e565b6000546001600160a01b0316331461063e5760405162461bcd60e51b81526004016106359061411b565b60405180910390fd5b610646612c60565b600354604080519182526020820183905233917feedc6338c9c1ad8f3cd6c90dd09dbe98dbd57e610d3e59a17996d07acb0d9511910160405180910390a2600355565b6004818154811061069957600080fd5b600091825260209091206008909102018054600182015460028301546003840154600485015460058601546006909601546001600160a01b03909516965092949193909261ffff16919087565b6000546001600160a01b031633146107105760405162461bcd60e51b81526004016106359061411b565b600454869081106107335760405162461bcd60e51b815260040161063590614150565b600a8211156107845760405162461bcd60e51b815260206004820152601760248201527f7365743a20746f6f206d616e79207265776172646572730000000000000000006044820152606401610635565b6103e861ffff861611156107da5760405162461bcd60e51b815260206004820152601960248201527f7365743a206465706f7369742066656520746f6f2068696768000000000000006044820152606401610635565b6212750084111561082d5760405162461bcd60e51b815260206004820152601d60248201527f7365743a20696e76616c6964206861727665737420696e74657276616c0000006044820152606401610635565b60005b828110156108c45761086884848381811061084d5761084d61417d565b90506020020160208101906108629190613e9b565b3b151590565b6108b45760405162461bcd60e51b815260206004820152601e60248201527f6164643a207265776172646572206d75737420626520636f6e747261637400006044820152606401610635565b6108bd816141a9565b9050610830565b506108cd612c60565b85600488815481106108e1576108e161417d565b90600052602060002090600802016001015460065461090091906141c4565b61090a91906141db565b60068190555085600488815481106109245761092461417d565b906000526020600020906008020160010181905550846004888154811061094d5761094d61417d565b906000526020600020906008020160040160006101000a81548161ffff021916908361ffff160217905550836004888154811061098c5761098c61417d565b9060005260206000209060080201600501819055508282600489815481106109b6576109b661417d565b906000526020600020906008020160070191906109d4929190613ca3565b5082826040516109e59291906141f3565b6040805191829003822088835261ffff881660208401529082018690529088907f5ed6f0deef9ab49d02900b40d596df4cd637a2a7fbfa56bbcb377389d3ce8d289060600160405180910390a350505050505050565b60045460009083908110610a615760405162461bcd60e51b815260040161063590614150565b60008481526005602090815260408083206001600160a01b038716845290915290206007544210801590610a99575080600301544210155b95945050505050565b600c546001600160a01b03163314610b2c5760405162461bcd60e51b815260206004820152604160248201527f73657420696e766573746f7220616464726573733a206f6e6c7920707265766960448201527f6f757320696e766573746f722063616e2063616c6c2074686973206d6574686f6064820152601960fa1b608482015260a401610635565b600c80546001600160a01b0319166001600160a01b03831690811790915560405133907f6260cb34f06b782e83bde168f7d74ab2133041cb53b63ce22b127822a92b679190600090a350565b60026001541415610b9b5760405162461bcd60e51b815260040161063590614235565b600260015560045482908110610bc35760405162461bcd60e51b815260040161063590614150565b600060048481548110610bd857610bd861417d565b600091825260208083208784526005825260408085203386529092529220805460089092029092019250841115610c515760405162461bcd60e51b815260206004820181905260248201527f77697468647261773a207573657220616d6f756e74206e6f7420656e6f7567686044820152606401610635565b8382600601541015610ca55760405162461bcd60e51b815260206004820152601f60248201527f77697468647261773a20706f6f6c20746f74616c206e6f7420656e6f756768006044820152606401610635565b610cae85612c86565b610cb78561307c565b8315610d1c5783816000016000828254610cd191906141c4565b909155505060025482546001600160a01b0390811691161415610d06578360096000828254610d0091906141c4565b90915550505b8154610d1c906001600160a01b0316338661322b565b600382015481547f000000000000000000000000000000000000000000000000000000000000000091610d4e9161426c565b610d58919061428b565b600182015560005b6007830154811015610e0957826007018181548110610d8157610d8161417d565b600091825260209091200154825460405163fe8343fb60e01b81526004810189905233602482015260448101919091526001600160a01b039091169063fe8343fb90606401600060405180830381600087803b158015610de057600080fd5b505af1158015610df4573d6000803e3d6000fd5b5050505080610e02906141a9565b9050610d60565b508315610e2a5783826006016000828254610e2491906141c4565b90915550505b604051848152859033907ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b5689060200160405180910390a3505060018055505050565b606080606080846004805490508110610e975760405162461bcd60e51b815260040161063590614150565b600060048781548110610eac57610eac61417d565b9060005260206000209060080201905080600701805490506001610ed091906141db565b6001600160401b03811115610ee757610ee76142ad565b604051908082528060200260200182016040528015610f10578160200160208202803683370190505b506007820154909650610f249060016141db565b6001600160401b03811115610f3b57610f3b6142ad565b604051908082528060200260200182016040528015610f6e57816020015b6060815260200190600190039081610f595790505b506007820154909550610f829060016141db565b6001600160401b03811115610f9957610f996142ad565b604051908082528060200260200182016040528015610fc2578160200160208202803683370190505b506007820154909450610fd69060016141db565b6001600160401b03811115610fed57610fed6142ad565b604051908082528060200260200182016040528015611016578160200160208202803683370190505b5060025487519194506001600160a01b031690879060009061103a5761103a61417d565b6001600160a01b03928316602091820292909201015260025461105d9116613346565b856000815181106110705761107061417d565b6020908102919091010152600254611090906001600160a01b0316613409565b60ff16846000815181106110a6576110a661417d565b60200260200101818152505060065460035482600101546110c7919061426c565b6110d1919061428b565b836000815181106110e4576110e461417d565b60200260200101818152505060005b6007820154811015611442578160070181815481106111145761111461417d565b600091825260209182902001546040805163f7c618c160e01b815290516001600160a01b039092169263f7c618c192600480840193829003018186803b15801561115d57600080fd5b505afa158015611171573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061119591906142c3565b876111a18360016141db565b815181106111b1576111b161417d565b60200260200101906001600160a01b031690816001600160a01b0316815250506112788260070182815481106111e9576111e961417d565b600091825260209182902001546040805163f7c618c160e01b815290516001600160a01b039092169263f7c618c192600480840193829003018186803b15801561123257600080fd5b505afa158015611246573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061126a91906142c3565b6001600160a01b0316613346565b866112848360016141db565b815181106112945761129461417d565b60200260200101819052506113468260070182815481106112b7576112b761417d565b600091825260209182902001546040805163f7c618c160e01b815290516001600160a01b039092169263f7c618c192600480840193829003018186803b15801561130057600080fd5b505afa158015611314573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061133891906142c3565b6001600160a01b0316613409565b60ff16856113558360016141db565b815181106113655761136561417d565b6020026020010181815250508160070181815481106113865761138661417d565b600091825260209091200154604051631197a07b60e21b8152600481018a90526001600160a01b039091169063465e81ec9060240160206040518083038186803b1580156113d357600080fd5b505afa1580156113e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061140b91906142e0565b846114178360016141db565b815181106114275761142761417d565b602090810291909101015261143b816141a9565b90506110f3565b5050509193509193565b6000546001600160a01b031633146114765760405162461bcd60e51b81526004016106359061411b565b600a8111156114c75760405162461bcd60e51b815260206004820152601760248201527f6164643a20746f6f206d616e79207265776172646572730000000000000000006044820152606401610635565b6103e861ffff8516111561151d5760405162461bcd60e51b815260206004820152601960248201527f6164643a206465706f7369742066656520746f6f2068696768000000000000006044820152606401610635565b621275008311156115705760405162461bcd60e51b815260206004820152601d60248201527f6164643a20696e76616c6964206861727665737420696e74657276616c0000006044820152606401610635565b843b6115cd5760405162461bcd60e51b815260206004820152602660248201527f6164643a204c5020746f6b656e206d75737420626520612076616c696420636f6044820152651b9d1c9858dd60d21b6064820152608401610635565b60005b81811015611649576115ed83838381811061084d5761084d61417d565b6116395760405162461bcd60e51b815260206004820152601e60248201527f6164643a207265776172646572206d75737420626520636f6e747261637400006044820152606401610635565b611642816141a9565b90506115d0565b50611652612c60565b6000600754421161166557600754611667565b425b9050866006600082825461167b91906141db565b925050819055506004604051806101000160405280886001600160a01b03168152602001898152602001838152602001600081526020018761ffff168152602001868152602001600081526020018585808060200260200160405190810160405280939291908181526020018383602002808284376000920182905250939094525050835460018082018655948252602091829020845160089092020180546001600160a01b0319166001600160a01b0390921691909117815583820151948101949094556040830151600285015560608301516003850155608083015160048501805461ffff191661ffff90921691909117905560a0830151600585015560c0830151600685015560e083015180519394936117a2935060078501929190910190613d06565b50505082826040516117b59291906141f3565b6040519081900390206004546001600160a01b038816906117d8906001906141c4565b604080518b815261ffff8a1660208201529081018890527f5ed295c4f5af5aeb1ccd905e1cd55a86ab3bb9fc1fe2346ff64ac47dbef366619060600160405180910390a450505050505050565b600260015414156118485760405162461bcd60e51b815260040161063590614235565b6002600155600454869081106118705760405162461bcd60e51b815260040161063590614150565b6000600488815481106118855761188561417d565b60009182526020909120600890910201805460405163d505accf60e01b8152336004820152306024820152604481018a90526064810189905260ff8816608482015260a4810187905260c481018690529192506001600160a01b031690819063d505accf9060e401600060405180830381600087803b15801561190757600080fd5b505af115801561191b573d6000803e3d6000fd5b5050505061192989896134c1565b50506001805550505050505050565b6002600154141561195b5760405162461bcd60e51b815260040161063590614235565b600260015561196981612c86565b5060018055565b600260015414156119935760405162461bcd60e51b815260040161063590614235565b60026001819055506000600482815481106119b0576119b061417d565b60009182526020808320858452600582526040808520338652909252922080546008929092029092016006810154909350811115611a425760405162461bcd60e51b815260206004820152602960248201527f656d657267656e63792077697468647261773a20706f6f6c20746f74616c206e6044820152680dee840cadcdeeaced60bb1b6064820152608401610635565b6000808355600183018190556002830181905560038301819055600684018054839290611a709084906141c4565b90915550600090505b6007840154811015611b1d57836007018181548110611a9a57611a9a61417d565b600091825260208220015460405163fe8343fb60e01b81526004810188905233602482015260448101929092526001600160a01b03169063fe8343fb90606401600060405180830381600087803b158015611af457600080fd5b505af1158015611b08573d6000803e3d6000fd5b5050505080611b16906141a9565b9050611a79565b5060025483546001600160a01b0390811691161415611b4e578060096000828254611b4891906141c4565b90915550505b8254611b64906001600160a01b0316338361322b565b604051818152849033907fbb757047c2b5f3974fe26b7c10f732e7bce710b0952a71082702781e62ae05959060200160405180910390a35050600180555050565b60026001541415611bc85760405162461bcd60e51b815260040161063590614235565b6002600155611bd5612c60565b60018055565b600060048281548110611bf057611bf061417d565b9060005260206000209060080201600601549050919050565b600b546001600160a01b03163314611c9b5760405162461bcd60e51b815260206004820152604960248201527f73657420747265617375727920616464726573733a206f6e6c7920707265766960448201527f6f757320747265617375727920616464726573732063616e2063616c6c2074686064820152681a5cc81b595d1a1bd960ba1b608482015260a401610635565b600b80546001600160a01b0319166001600160a01b03831690811790915560405133907f61885cdba916be748ff3e3f6f15e4206153b8ea3b7acabade9d04b4063a8351090600090a350565b600a546001600160a01b03163314611d715760405162461bcd60e51b815260206004820152604160248201527f736574207465616d20616464726573733a206f6e6c792070726576696f75732060448201527f7465616d20616464726573732063616e2063616c6c2074686973206d6574686f6064820152601960fa1b608482015260a401610635565b600a80546001600160a01b0319166001600160a01b03831690811790915560405133907f42fbc17d847fdc3e5c82da842a5ef3979c64f3b94cd4e7382310fd5525c6ee0f90600090a350565b6000546001600160a01b03163314611de75760405162461bcd60e51b81526004016106359061411b565b611df1600061384f565b565b6000546001600160a01b03163314611e1d5760405162461bcd60e51b81526004016106359061411b565b6103e8811115611e835760405162461bcd60e51b815260206004820152602b60248201527f73657420696e766573746f722070657263656e743a20696e76616c696420706560448201526a7263656e742076616c756560a81b6064820152608401610635565b6103e8600e5482600d54611e9791906141db565b611ea191906141db565b1115611f045760405162461bcd60e51b815260206004820152602c60248201527f73657420696e766573746f722070657263656e743a20746f74616c207065726360448201526b0cadce840deeccae440dac2f60a31b6064820152608401610635565b600f5460408051918252602082018390527f204a076f4a2e4e5e646bb8841cc285306bf747e277f40dbfd5750e782e17b7a6910160405180910390a1600f55565b6000546001600160a01b03163314611f6f5760405162461bcd60e51b81526004016106359061411b565b6103e8811115611fd55760405162461bcd60e51b815260206004820152602b60248201527f7365742074726561737572792070657263656e743a20696e76616c696420706560448201526a7263656e742076616c756560a81b6064820152608401610635565b6103e8600f5482600d54611fe991906141db565b611ff391906141db565b11156120565760405162461bcd60e51b815260206004820152602c60248201527f7365742074726561737572792070657263656e743a20746f74616c207065726360448201526b0cadce840deeccae440dac2f60a31b6064820152608401610635565b600e5460408051918252602082018390527f204a076f4a2e4e5e646bb8841cc285306bf747e277f40dbfd5750e782e17b7a6910160405180910390a1600e55565b6000546001600160a01b031633146120c15760405162461bcd60e51b81526004016106359061411b565b6103e88111156121235760405162461bcd60e51b815260206004820152602760248201527f736574207465616d2070657263656e743a20696e76616c69642070657263656e604482015266742076616c756560c81b6064820152608401610635565b6103e8600f5482600e5461213791906141db565b61214191906141db565b11156121a05760405162461bcd60e51b815260206004820152602860248201527f736574207465616d2070657263656e743a20746f74616c2070657263656e74206044820152670deeccae440dac2f60c31b6064820152608401610635565b600d5460408051918252602082018390527f204a076f4a2e4e5e646bb8841cc285306bf747e277f40dbfd5750e782e17b7a6910160405180910390a1600d55565b6000546001600160a01b0316331461220b5760405162461bcd60e51b81526004016106359061411b565b60075442106122685760405162461bcd60e51b815260206004820152602360248201527f7374617274206661726d696e673a206661726d207374617274656420616c726560448201526261647960e81b6064820152608401610635565b60045460005b818110156122b65760006004828154811061228b5761228b61417d565b9060005260206000209060080201905042816002018190555050806122af906141a9565b905061226e565b505042600755565b600260015414156122e15760405162461bcd60e51b815260040161063590614235565b6002600155601e8111156123375760405162461bcd60e51b815260206004820152601f60248201527f68617276657374206d616e793a20746f6f206d616e7920706f6f6c20696473006044820152606401610635565b60005b8181101561237f5760045481101561236f5761236f8383838181106123615761236161417d565b9050602002013560006134c1565b612378816141a9565b905061233a565b50506001805550565b600260015414156123ab5760405162461bcd60e51b815260040161063590614235565b60026001556123ba82826134c1565b505060018055565b6000546001600160a01b031633146123ec5760405162461bcd60e51b81526004016106359061411b565b6123f4612c60565b336001600160a01b03167f802633c8d26237616d81bdac01bc40fcdf36e098832601582ec19d7e431c5ef3600484815481106124325761243261417d565b9060005260206000209060080201600101548360405161245c929190918252602082015260400190565b60405180910390a280600483815481106124785761247861417d565b90600052602060002090600802016001015460065461249791906141c4565b6124a191906141db565b60068190555080600483815481106124bb576124bb61417d565b9060005260206000209060080201600101819055505050565b600454606090829081106124fa5760405162461bcd60e51b815260040161063590614150565b60006004848154811061250f5761250f61417d565b9060005260206000209060080201905060005b600782015481101561259b578160070181815481106125435761254361417d565b9060005260206000200160009054906101000a90046001600160a01b03168482815181106125735761257361417d565b6001600160a01b0390921660209283029190910190910152612594816141a9565b9050612522565b505050919050565b6000546001600160a01b031633146125cd5760405162461bcd60e51b81526004016106359061411b565b6001600160a01b0381166126325760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610635565b61263b8161384f565b50565b6060806060808560048054905081106126695760405162461bcd60e51b815260040161063590614150565b60006004888154811061267e5761267e61417d565b600091825260208083208b84526005825260408085206001600160a01b038d16865290925292206003600890920290920190810154600682015460028301549294509091421180156126cf57508015155b156127a15760008460020154426126e691906141c4565b90506000600f54600e54600d546103e861270091906141c4565b61270a91906141c4565b61271491906141c4565b905060006103e882600654896001015460035487612732919061426c565b61273c919061426c565b612746919061428b565b612750919061426c565b61275a919061428b565b9050836127877f00000000000000000000000000000000000000000000000000000000000000008361426c565b612791919061428b565b61279b90866141db565b94505050505b6000836002015484600101547f00000000000000000000000000000000000000000000000000000000000000008587600001546127de919061426c565b6127e8919061428b565b6127f291906141c4565b6127fc91906141db565b600786015490915061280f9060016141db565b6001600160401b03811115612826576128266142ad565b60405190808252806020026020018201604052801561284f578160200160208202803683370190505b506007860154909a506128639060016141db565b6001600160401b0381111561287a5761287a6142ad565b6040519080825280602002602001820160405280156128ad57816020015b60608152602001906001900390816128985790505b5060078601549099506128c19060016141db565b6001600160401b038111156128d8576128d86142ad565b604051908082528060200260200182016040528015612901578160200160208202803683370190505b5060078601549097506129159060016141db565b6001600160401b0381111561292c5761292c6142ad565b604051908082528060200260200182016040528015612955578160200160208202803683370190505b506002548b519199506001600160a01b0316908b906000906129795761297961417d565b6001600160a01b03928316602091820292909201015260025461299c9116613346565b896000815181106129af576129af61417d565b60209081029190910101526002546129cf906001600160a01b0316613409565b60ff16886000815181106129e5576129e561417d565b6020026020010181815250508087600081518110612a0557612a0561417d565b60200260200101818152505060005b6007860154811015612c5057856007018181548110612a3557612a3561417d565b600091825260209182902001546040805163f7c618c160e01b815290516001600160a01b039092169263f7c618c192600480840193829003018186803b158015612a7e57600080fd5b505afa158015612a92573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ab691906142c3565b8b612ac28360016141db565b81518110612ad257612ad261417d565b60200260200101906001600160a01b031690816001600160a01b031681525050612b0a8660070182815481106111e9576111e961417d565b8a612b168360016141db565b81518110612b2657612b2661417d565b6020026020010181905250612b498660070182815481106112b7576112b761417d565b60ff1689612b588360016141db565b81518110612b6857612b6861417d565b602002602001018181525050856007018181548110612b8957612b8961417d565b60009182526020909120015460405160016232bd9d60e01b03198152600481018f90526001600160a01b038e811660248301529091169063ffcd42639060440160206040518083038186803b158015612be157600080fd5b505afa158015612bf5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c1991906142e0565b88612c258360016141db565b81518110612c3557612c3561417d565b6020908102919091010152612c49816141a9565b9050612a14565b5050505050505092959194509250565b60005b60045481101561263b57612c7681612c86565b612c7f816141a9565b9050612c63565b60045481908110612ca95760405162461bcd60e51b815260040161063590614150565b600060048381548110612cbe57612cbe61417d565b9060005260206000209060080201905080600201544211612cde57505050565b6006810154801580612cf257506001820154155b15612d035750426002909101555050565b6000826002015442612d1591906141c4565b90506000600654846001015460035484612d2f919061426c565b612d39919061426c565b612d43919061428b565b90506000600f54600e54600d546103e8612d5d91906141c4565b612d6791906141c4565b612d7191906141c4565b600254600a54600d549293506001600160a01b03918216926340c10f1992909116906103e890612da1908761426c565b612dab919061428b565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015612df157600080fd5b505af1158015612e05573d6000803e3d6000fd5b5050600254600b54600e546001600160a01b0392831694506340c10f1993509116906103e890612e35908761426c565b612e3f919061428b565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015612e8557600080fd5b505af1158015612e99573d6000803e3d6000fd5b5050600254600c54600f546001600160a01b0392831694506340c10f1993509116906103e890612ec9908761426c565b612ed3919061428b565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015612f1957600080fd5b505af1158015612f2d573d6000803e3d6000fd5b50506002546001600160a01b031691506340c10f199050306103e8612f52858761426c565b612f5c919061428b565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015612fa257600080fd5b505af1158015612fb6573d6000803e3d6000fd5b505050506103e88186600601547f000000000000000000000000000000000000000000000000000000000000000085612fef919061426c565b612ff9919061428b565b613003919061426c565b61300d919061428b565b85600301600082825461302091906141db565b909155505042600286018190556003860154604080519283526020830187905282015287907f3be3541fc42237d611b30329040bfa4569541d156560acdbbae57640d20b8f469060600160405180910390a250505050505b5050565b6000600482815481106130915761309161417d565b6000918252602080832085845260058252604080852033865290925292206003810154600890920290920192501580156130cd57506007544210155b156130e75760058201546130e190426141db565b60038201555b600081600101547f000000000000000000000000000000000000000000000000000000000000000084600301548460000154613123919061426c565b61312d919061428b565b61313791906141c4565b90506131438433610a3b565b156131b557600081118061315b575060008260020154115b156131b05781600201546008600082825461317691906141c4565b909155505060006002830155600583015461319190426141db565b600383015560028201546131b09033906131ab90846141db565b61389f565b613225565b80156132255780600860008282546131cd91906141db565b92505081905550808260020160008282546131e891906141db565b9091555050604051818152849033907fee470483107f579a55c754fa00613c45a9a3b617a418b39cb0be97e5381ba7c19060200160405180910390a35b50505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b179052915160009283929087169161328791906142f9565b6000604051808303816000865af19150503d80600081146132c4576040519150601f19603f3d011682016040523d82523d6000602084013e6132c9565b606091505b50915091508180156132f35750805115806132f35750808060200190518101906132f39190614315565b61333f5760405162461bcd60e51b815260206004820152601c60248201527f426f72696e6745524332303a205472616e73666572206661696c6564000000006044820152606401610635565b5050505050565b60408051600481526024810182526020810180516001600160e01b03166395d89b4160e01b179052905160609160009182916001600160a01b0386169161338d91906142f9565b600060405180830381855afa9150503d80600081146133c8576040519150601f19603f3d011682016040523d82523d6000602084013e6133cd565b606091505b5091509150816133f857604051806040016040528060038152602001623f3f3f60e81b815250613401565b613401816139ef565b949350505050565b60408051600481526024810182526020810180516001600160e01b031663313ce56760e01b1790529051600091829182916001600160a01b0386169161344f91906142f9565b600060405180830381855afa9150503d806000811461348a576040519150601f19603f3d011682016040523d82523d6000602084013e61348f565b606091505b50915091508180156134a2575080516020145b6134ad576012613401565b808060200190518101906134019190614337565b600454829081106134e45760405162461bcd60e51b815260040161063590614150565b6000600484815481106134f9576134f961417d565b6000918252602080832087845260058252604080852033865290925292206008909102909101915061352a85612c86565b6135338561307c565b83156137035781546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b15801561357c57600080fd5b505afa158015613590573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135b491906142e0565b83549091506135ce906001600160a01b0316333088613b7f565b82546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b15801561361157600080fd5b505afa158015613625573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061364991906142e0565b905061365582826141c4565b600485015490965061ffff16156136b7576004840154600090612710906136809061ffff168961426c565b61368a919061428b565b600b5486549192506136a9916001600160a01b0390811691168361322b565b6136b381886141c4565b9650505b858360000160008282546136cb91906141db565b909155505060025484546001600160a01b03908116911614156137005785600960008282546136fa91906141db565b90915550505b50505b600382015481547f0000000000000000000000000000000000000000000000000000000000000000916137359161426c565b61373f919061428b565b600182015560005b60078301548110156137f0578260070181815481106137685761376861417d565b600091825260209091200154825460405163fe8343fb60e01b81526004810189905233602482015260448101919091526001600160a01b039091169063fe8343fb90606401600060405180830381600087803b1580156137c757600080fd5b505af11580156137db573d6000803e3d6000fd5b50505050806137e9906141a9565b9050613747565b508315613811578382600601600082825461380b91906141db565b90915550505b604051848152859033907f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a159060200160405180910390a35050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6009546002546040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b1580156138e557600080fd5b505afa1580156138f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061391d91906142e0565b1115613078576009546002546040516370a0823160e01b8152306004820152600092916001600160a01b0316906370a082319060240160206040518083038186803b15801561396b57600080fd5b505afa15801561397f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139a391906142e0565b6139ad91906141c4565b90508082106139d2576002546139cd906001600160a01b0316848361322b565b505050565b81156139cd576002546139cd906001600160a01b0316848461322b565b60606040825110613a145781806020019051810190613a0e9190614354565b92915050565b815160201415613b5b5760005b60208160ff16108015613a565750828160ff1681518110613a4457613a4461417d565b01602001516001600160f81b03191615155b15613a6d5780613a65816143f5565b915050613a21565b60008160ff166001600160401b03811115613a8a57613a8a6142ad565b6040519080825280601f01601f191660200182016040528015613ab4576020820181803683370190505b509050600091505b60208260ff16108015613af15750838260ff1681518110613adf57613adf61417d565b01602001516001600160f81b03191615155b15613b5457838260ff1681518110613b0b57613b0b61417d565b602001015160f81c60f81b818360ff1681518110613b2b57613b2b61417d565b60200101906001600160f81b031916908160001a90535081613b4c816143f5565b925050613abc565b9392505050565b50506040805180820190915260038152623f3f3f60e81b602082015290565b919050565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b1790529151600092839290881691613be391906142f9565b6000604051808303816000865af19150503d8060008114613c20576040519150601f19603f3d011682016040523d82523d6000602084013e613c25565b606091505b5091509150818015613c4f575080511580613c4f575080806020019051810190613c4f9190614315565b613c9b5760405162461bcd60e51b815260206004820181905260248201527f426f72696e6745524332303a205472616e7366657246726f6d206661696c65646044820152606401610635565b505050505050565b828054828255906000526020600020908101928215613cf6579160200282015b82811115613cf65781546001600160a01b0319166001600160a01b03843516178255602090920191600190910190613cc3565b50613d02929150613d5b565b5090565b828054828255906000526020600020908101928215613cf6579160200282015b82811115613cf657825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190613d26565b5b80821115613d025760008155600101613d5c565b600060208284031215613d8257600080fd5b5035919050565b803561ffff81168114613b7a57600080fd5b60008083601f840112613dad57600080fd5b5081356001600160401b03811115613dc457600080fd5b6020830191508360208260051b8501011115613ddf57600080fd5b9250929050565b60008060008060008060a08789031215613dff57600080fd5b8635955060208701359450613e1660408801613d89565b93506060870135925060808701356001600160401b03811115613e3857600080fd5b613e4489828a01613d9b565b979a9699509497509295939492505050565b6001600160a01b038116811461263b57600080fd5b60008060408385031215613e7e57600080fd5b823591506020830135613e9081613e56565b809150509250929050565b600060208284031215613ead57600080fd5b8135613b5481613e56565b60008060408385031215613ecb57600080fd5b50508035926020909101359150565b600081518084526020808501945080840160005b83811015613f135781516001600160a01b031687529582019590820190600101613eee565b509495945050505050565b60005b83811015613f39578181015183820152602001613f21565b838111156132255750506000910152565b600081518084526020808501945080840160005b83811015613f1357815187529582019590820190600101613f5e565b608081526000613f8d6080830187613eda565b6020838203818501528187518084528284019150828160051b850101838a0160005b83811015613ff557601f198088850301865282518051808652613fd7818a88018b8501613f1e565b96880196601f01909116939093018601925090850190600101613faf565b50508681036040880152614009818a613f4a565b94505050505082810360608401526140218185613f4a565b979650505050505050565b60008060008060008060a0878903121561404557600080fd5b86359550602087013561405781613e56565b9450613e1660408801613d89565b60ff8116811461263b57600080fd5b60008060008060008060c0878903121561408d57600080fd5b86359550602087013594506040870135935060608701356140ad81614065565b9598949750929560808101359460a0909101359350915050565b600080602083850312156140da57600080fd5b82356001600160401b038111156140f057600080fd5b6140fc85828601613d9b565b90969095509350505050565b602081526000613b546020830184613eda565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b602080825260139082015272141bdbdb08191bd95cc81b9bdd08195e1a5cdd606a1b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60006000198214156141bd576141bd614193565b5060010190565b6000828210156141d6576141d6614193565b500390565b600082198211156141ee576141ee614193565b500190565b60008184825b8581101561422a57813561420c81613e56565b6001600160a01b0316835260209283019291909101906001016141f9565b509095945050505050565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b600081600019048311821515161561428657614286614193565b500290565b6000826142a857634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052604160045260246000fd5b6000602082840312156142d557600080fd5b8151613b5481613e56565b6000602082840312156142f257600080fd5b5051919050565b6000825161430b818460208701613f1e565b9190910192915050565b60006020828403121561432757600080fd5b81518015158114613b5457600080fd5b60006020828403121561434957600080fd5b8151613b5481614065565b60006020828403121561436657600080fd5b81516001600160401b038082111561437d57600080fd5b818401915084601f83011261439157600080fd5b8151818111156143a3576143a36142ad565b604051601f8201601f19908116603f011681019083821181831017156143cb576143cb6142ad565b816040528281528760208487010111156143e457600080fd5b614021836020830160208801613f1e565b600060ff821660ff81141561440c5761440c614193565b6001019291505056fea2646970667358221220475a0a5dd9869f1cfb67df4904b19132f8121a1685750959ac03dd0c66ae45c664736f6c63430008090033
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for
interesting conversations.