Stonks
0x910c784111ee4a16e59cf441c48fb23cf3cd0844
Verification
Verified
v0.8.17+commit.8df45f5f
Type
Contract
4,684 bytes
ABI entries
32
19 read · 8 write
License
mit
Contract information
- Address
- 0x910c784111ee4a16e59cf441c48fb23cf3cd0844
- Chain
- Robinhood Chain (4663)
- Compiler
- v0.8.17+commit.8df45f5f
- Optimization
- Enabled
- Creator
- 0x77Be026D34…56AFAC243b
- Creation tx
- 0x6d54bb7b0b…06b619ff08
Token
Not a token
This contract does not expose ERC-20 metadata.
Read contract (19)
STONKS_TO_INCREASE_MULTIPLIER_BY_ONE() → uint256
calculateStonksBuy(uint256, uint256) → uint256
calculateStonksBuySimple(uint256) → uint256
calculateStonksSell(uint256) → uint256
deposited(address) → uint256
devFeeVal() → uint256
getMyStonks(address) → uint256
getStonksAccumulationValue(address) → uint256
getStonksSinceLastHireTime(address) → uint256
lastHireTime(address) → uint256
multipliers(address) → uint256
refShare() → uint256
rewardsClaimed(address) → uint256
stonksAccumulated(address) → uint256
stonksBalance(address) → uint256
stonksRewardsToEth(address) → uint256
userReferral(bytes4) → address
wlRefShare() → uint256
wlReferrals(bytes4) → bool
Events (3)
ReferralGeneratedStonksBoughtStonksSold
ABI
[
{
"inputs": [
{
"internalType": "address",
"name": "_owner",
"type": "address"
},
{
"internalType": "address",
"name": "_platform",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "bytes4",
"name": "refCode",
"type": "bytes4"
},
{
"indexed": false,
"internalType": "address",
"name": "_user",
"type": "address"
}
],
"name": "ReferralGenerated",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "_amount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "address",
"name": "_user",
"type": "address"
},
{
"indexed": false,
"internalType": "bytes4",
"name": "_ref",
"type": "bytes4"
}
],
"name": "StonksBought",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "_amount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "address",
"name": "_user",
"type": "address"
}
],
"name": "StonksSold",
"type": "event"
},
{
"inputs": [],
"name": "STONKS_TO_INCREASE_MULTIPLIER_BY_ONE",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes4",
"name": "_ref",
"type": "bytes4"
}
],
"name": "buyStonks",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "ethAmount",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "contractBalance",
"type": "uint256"
}
],
"name": "calculateStonksBuy",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "ethAmount",
"type": "uint256"
}
],
"name": "calculateStonksBuySimple",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "stonksAmount",
"type": "uint256"
}
],
"name": "calculateStonksSell",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "compoundAll",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "deposited",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "devFeeVal",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "user",
"type": "address"
}
],
"name": "getMyStonks",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "user",
"type": "address"
}
],
"name": "getStonksAccumulationValue",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "user",
"type": "address"
}
],
"name": "getStonksSinceLastHireTime",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "lastHireTime",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "multipliers",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "refShare",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "rewardsClaimed",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "sellStonks",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "stonksAccumulated",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "stonksBalance",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "user",
"type": "address"
}
],
"name": "stonksRewardsToEth",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_devFeeVal",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "_refShare",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "_wlRefShare",
"type": "uint256"
}
],
"name": "updateFees",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_newOwner",
"type": "address"
}
],
"name": "updateOwner",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_newPlatform",
"type": "address"
}
],
"name": "updatePlatform",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_rate",
"type": "uint256"
}
],
"name": "updateRate",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes4",
"name": "",
"type": "bytes4"
}
],
"name": "userReferral",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes4",
"name": "_ref",
"type": "bytes4"
}
],
"name": "whitelistReferral",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "wlRefShare",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes4",
"name": "",
"type": "bytes4"
}
],
"name": "wlReferrals",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"stateMutability": "payable",
"type": "receive"
}
]Source code
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;
// https://x.com/stonksfarm
// https://stonks.farm
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)
library Math {
enum Rounding {
Down, // Toward negative infinity
Up, // Toward infinity
Zero // Toward zero
}
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two numbers. The result is rounded towards
* zero.
*/
function average(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b) / 2 can overflow.
return (a & b) + (a ^ b) / 2;
}
/**
* @dev Returns the ceiling of the division of two numbers.
*
* This differs from standard division with `/` in that it rounds up instead
* of rounding down.
*/
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b - 1) / b can overflow on addition, so we distribute.
return a == 0 ? 0 : (a - 1) / b + 1;
}
/**
* @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
* @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
* with further edits by Uniswap Labs also under MIT license.
*/
function mulDiv(
uint256 x,
uint256 y,
uint256 denominator
) internal pure returns (uint256 result) {
unchecked {
// 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
// use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
// variables such that product = prod1 * 2^256 + prod0.
uint256 prod0; // Least significant 256 bits of the product
uint256 prod1; // Most significant 256 bits of the product
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
// Handle non-overflow cases, 256 by 256 division.
if (prod1 == 0) {
return prod0 / denominator;
}
// Make sure the result is less than 2^256. Also prevents denominator == 0.
require(denominator > prod1);
///////////////////////////////////////////////
// 512 by 256 division.
///////////////////////////////////////////////
// Make division exact by subtracting the remainder from [prod1 prod0].
uint256 remainder;
assembly {
// Compute remainder using mulmod.
remainder := mulmod(x, y, denominator)
// Subtract 256 bit number from 512 bit number.
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
// Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
// See https://cs.stackexchange.com/q/138556/92363.
// Does not overflow because the denominator cannot be zero at this stage in the function.
uint256 twos = denominator & (~denominator + 1);
assembly {
// Divide denominator by twos.
denominator := div(denominator, twos)
// Divide [prod1 prod0] by twos.
prod0 := div(prod0, twos)
// Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
twos := add(div(sub(0, twos), twos), 1)
}
// Shift in bits from prod1 into prod0.
prod0 |= prod1 * twos;
// Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
// that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
// four bits. That is, denominator * inv = 1 mod 2^4.
uint256 inverse = (3 * denominator) ^ 2;
// Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
// in modular arithmetic, doubling the correct bits in each step.
inverse *= 2 - denominator * inverse; // inverse mod 2^8
inverse *= 2 - denominator * inverse; // inverse mod 2^16
inverse *= 2 - denominator * inverse; // inverse mod 2^32
inverse *= 2 - denominator * inverse; // inverse mod 2^64
inverse *= 2 - denominator * inverse; // inverse mod 2^128
inverse *= 2 - denominator * inverse; // inverse mod 2^256
// Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
// This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
// less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
// is no longer required.
result = prod0 * inverse;
return result;
}
}
/**
* @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
*/
function mulDiv(
uint256 x,
uint256 y,
uint256 denominator,
Rounding rounding
) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
/**
* @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
*
* Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
*/
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
// For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
//
// We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
// `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
//
// This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
// → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
// → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
//
// Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
uint256 result = 1 << (log2(a) >> 1);
// At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
// since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
// every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
// into the expected uint128 result.
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
/**
* @notice Calculates sqrt(a), following the selected rounding direction.
*/
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
}
}
/**
* @dev Return the log in base 2, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 2, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 10, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10**64) {
value /= 10**64;
result += 64;
}
if (value >= 10**32) {
value /= 10**32;
result += 32;
}
if (value >= 10**16) {
value /= 10**16;
result += 16;
}
if (value >= 10**8) {
value /= 10**8;
result += 8;
}
if (value >= 10**4) {
value /= 10**4;
result += 4;
}
if (value >= 10**2) {
value /= 10**2;
result += 2;
}
if (value >= 10**1) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 10, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 256, rounded down, of a positive value.
* Returns 0 if given 0.
*
* Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
*/
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 10, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);
}
}
}
// OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol)
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
// On the first call to nonReentrant, _status will be _NOT_ENTERED
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
}
function _nonReentrantAfter() private {
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
}
contract Stonks is ReentrancyGuard {
uint256 public STONKS_TO_INCREASE_MULTIPLIER_BY_ONE = 100 * 1 days / 25; //25% daily rate
uint256 internal constant PSN = 10_000;
uint256 internal constant PSNH = 5_000;
uint256 public devFeeVal = 5; //5%
uint256 public refShare = 25; //25%
uint256 public wlRefShare = 25; //25%
uint256 internal constant MAX_DEV_FEE = 10;
uint256 internal constant MAX_REF_SHARE = 30;
uint256 internal constant MAX_WL_REF_SHARE = 30;
uint256 internal constant DENOMINATOR = 100;
mapping (address => uint256) public multipliers;
mapping (address => uint256) public stonksBalance;
mapping (address => uint256) public lastHireTime;
mapping (address => uint256) public stonksAccumulated;
mapping (address => uint256) public deposited;
mapping (address => uint256) public rewardsClaimed;
mapping(bytes4 => address) public userReferral;
mapping (bytes4 => bool) public wlReferrals;
uint256 private marketStonks = 10_0000 * STONKS_TO_INCREASE_MULTIPLIER_BY_ONE;
address private platform;
address private owner;
constructor(address _owner, address _platform) {
owner = _owner;
platform = _platform;
}
modifier onlyOwner() {
require(owner == msg.sender, "Ownable: caller is not the owner");
_;
}
function _compound(uint256 _stonksToCompound) internal {
uint256 myStonkRewards = getStonksSinceLastHireTime(msg.sender);
stonksBalance[msg.sender] += myStonkRewards;
stonksAccumulated[msg.sender] += myStonkRewards;
require(_stonksToCompound <= stonksBalance[msg.sender], "Not enough Stonks");
uint256 newMultipliers = _stonksToCompound/STONKS_TO_INCREASE_MULTIPLIER_BY_ONE;
stonksBalance[msg.sender] -= (STONKS_TO_INCREASE_MULTIPLIER_BY_ONE * newMultipliers);
multipliers[msg.sender] += newMultipliers;
lastHireTime[msg.sender] = block.timestamp;
marketStonks += (STONKS_TO_INCREASE_MULTIPLIER_BY_ONE * newMultipliers) * 20 / DENOMINATOR; //market boost: add 20% to the market
}
function compoundAll() public nonReentrant {
uint256 myStonkRewards = getStonksSinceLastHireTime(msg.sender);
stonksBalance[msg.sender] += myStonkRewards;
stonksAccumulated[msg.sender] += myStonkRewards;
uint256 newMultipliers = stonksBalance[msg.sender]/STONKS_TO_INCREASE_MULTIPLIER_BY_ONE;
stonksBalance[msg.sender] -= (STONKS_TO_INCREASE_MULTIPLIER_BY_ONE * newMultipliers);
multipliers[msg.sender] += newMultipliers;
lastHireTime[msg.sender] = block.timestamp;
marketStonks += (STONKS_TO_INCREASE_MULTIPLIER_BY_ONE * newMultipliers) * 20 / DENOMINATOR; //market boost: add 20% to the market
}
function sellStonks() public nonReentrant {
uint256 hasStonks = getMyStonks(msg.sender);
uint256 stonksValue = calculateStonksSell(hasStonks);
uint256 fee = devFee(stonksValue);
stonksBalance[msg.sender] = 0;
lastHireTime[msg.sender] = block.timestamp;
marketStonks += hasStonks;
rewardsClaimed[msg.sender] += stonksValue - fee;
payable(platform).transfer(fee);
payable(msg.sender).transfer(stonksValue - fee);
emit StonksSold(stonksValue - fee, msg.sender);
}
function buyStonks(bytes4 _ref) external payable nonReentrant {
_buyStonks(_ref, msg.value);
emit StonksBought(msg.value, msg.sender, _ref);
}
function _buyStonks(bytes4 _ref, uint256 ethAmount) private {
bytes32 hash = keccak256(abi.encodePacked(msg.sender));
bytes4 refCode = bytes4(hash);
if (userReferral[refCode] == address(0)) {
userReferral[refCode] = msg.sender;
emit ReferralGenerated(refCode, msg.sender);
}
uint256 stonksBought = calculateStonksBuy(ethAmount, address(this).balance - ethAmount);
stonksBought -= devFee(stonksBought);
uint256 fee = devFee(ethAmount);
payable(platform).transfer(fee);
stonksBalance[msg.sender] += stonksBought;
stonksAccumulated[msg.sender] += stonksBought;
deposited[msg.sender] += ethAmount;
address _refAddr = userReferral[_ref];
if (_refAddr != address(0) && _refAddr != msg.sender) {
uint256 share = wlReferrals[_ref] ? wlRefShare : refShare;
stonksBalance[_refAddr] += stonksBought * share / DENOMINATOR;
}
_compound(stonksBought);
}
function stonksRewardsToEth(address user) external view returns(uint256) {
uint256 hasStonks = getMyStonks(user);
uint256 stonksValue;
try this.calculateStonksSell(hasStonks) returns (uint256 value) {stonksValue=value;} catch{}
return stonksValue;
}
function calculateTrade(uint256 rt, uint256 rs, uint256 bs) private pure returns(uint256) {
return (PSN * bs) / (PSNH + (PSN * rs + PSNH * rt) / rt);
}
function calculateStonksSell(uint256 stonksAmount) public view returns(uint256) {
return calculateTrade(stonksAmount, marketStonks, address(this).balance);
}
function calculateStonksBuy(uint256 ethAmount, uint256 contractBalance) public view returns(uint256) {
return calculateTrade(ethAmount, contractBalance, marketStonks);
}
function calculateStonksBuySimple(uint256 ethAmount) external view returns(uint256) {
return calculateStonksBuy(ethAmount, address(this).balance);
}
function devFee(uint256 amount) private view returns(uint256) {
return amount * devFeeVal / DENOMINATOR;
}
function getMyStonks(address user) public view returns(uint256) {
return stonksBalance[user] + getStonksSinceLastHireTime(user);
}
function getStonksSinceLastHireTime(address user) public view returns(uint256) {
return Math.min(STONKS_TO_INCREASE_MULTIPLIER_BY_ONE, block.timestamp - lastHireTime[user]) * multipliers[user];
}
function getStonksAccumulationValue(address user) public view returns(uint256) {
return Math.min(STONKS_TO_INCREASE_MULTIPLIER_BY_ONE, block.timestamp - lastHireTime[user]);
}
function updatePlatform(address _newPlatform) public onlyOwner {
platform = payable(_newPlatform);
}
function updateRate(uint256 _rate) public onlyOwner {
STONKS_TO_INCREASE_MULTIPLIER_BY_ONE = _rate;
}
function updateFees(uint256 _devFeeVal, uint256 _refShare, uint256 _wlRefShare) public onlyOwner {
require(_devFeeVal <= MAX_DEV_FEE, "Max dev fee exceeded");
require(_refShare <= MAX_REF_SHARE, "Max ref share exceeded");
require(_wlRefShare <= MAX_WL_REF_SHARE, "Max wl ref share exceeded");
devFeeVal = _devFeeVal;
refShare =_refShare;
wlRefShare = _wlRefShare;
}
function updateOwner(address _newOwner) public onlyOwner {
owner = _newOwner;
}
function whitelistReferral(bytes4 _ref) public onlyOwner {
wlReferrals[_ref] = true;
}
receive() external payable {}
event ReferralGenerated(bytes4 refCode, address _user);
event StonksBought(uint256 _amount, address _user, bytes4 _ref);
event StonksSold(uint256 _amount, address _user);
}
Chain explorer1858msChain node84ms