Transaction Hash:
Block:
12944276 at Aug-02-2021 06:04:40 AM +UTC
Transaction Fee:
0.006718272 ETH
$15.06
Gas Used:
279,928 Gas / 24 Gwei
Emitted Events:
110 |
FEG.Transfer( from=[Sender] 0x8482741006f65270655ff08d704126028207bdb6, to=[Receiver] FEGstakeV2, value=59945293151192154604 )
|
111 |
FEG.Approval( owner=[Sender] 0x8482741006f65270655ff08d704126028207bdb6, spender=[Receiver] FEGstakeV2, value=999999999999999938831333519191678976 )
|
112 |
FEGstakeV2.Transfer( src=0x0000000000000000000000000000000000000000, dst=[Receiver] FEGstakeV2, amt=59890233447565450162 )
|
113 |
FEGstakeV2.Transfer( src=[Receiver] FEGstakeV2, dst=[Sender] 0x8482741006f65270655ff08d704126028207bdb6, amt=59890233447565450162 )
|
114 |
FEGstakeV2.STAKED( staker=[Sender] 0x8482741006f65270655ff08d704126028207bdb6, tokens=61168666480808321024 )
|
Account State Difference:
Address | Before | After | State Difference | ||
---|---|---|---|---|---|
0x04668Ec2...D451c8F7F
Miner
| (zhizhu.top) | 148.3306789230705458 Eth | 148.3373971950705458 Eth | 0.006718272 | |
0x38999921...52522C945 | |||||
0x4a9D6b95...b20fa2358 | |||||
0x84827410...28207Bdb6 |
0.020355436030053241 Eth
Nonce: 66
|
0.013637164030053241 Eth
Nonce: 67
| 0.006718272 |
Execution Trace
FEGstakeV2.STAKE( tokens=61168666480808321024 ) => ( poolAmountOut=59890233447565450162 )

-
FEG.balanceOf( account=0x8482741006F65270655ff08d704126028207Bdb6 ) => ( 61168710610916826870 )
-
FEG.balanceOf( account=0x4a9D6b95459eb9532B7E4d82Ca214a3b20fa2358 ) => ( 3189644726870568276972930 )
-
FEGstakeV2.balanceOf( whom=0x8482741006F65270655ff08d704126028207Bdb6 ) => ( 0 )
-
FEGstakeV2.balanceOf( whom=0x8482741006F65270655ff08d704126028207Bdb6 ) => ( 0 )
-
FEGstakeV2.balanceOf( whom=0x8482741006F65270655ff08d704126028207Bdb6 ) => ( 0 )
-
FEG.transferFrom( sender=0x8482741006F65270655ff08d704126028207Bdb6, recipient=0x4a9D6b95459eb9532B7E4d82Ca214a3b20fa2358, amount=61168666480808321024 ) => ( True )
-
FEGstakeV2.transfer( dst=0x8482741006F65270655ff08d704126028207Bdb6, amt=59890233447565450162 ) => ( True )
STAKE[FEGstakeV2 (ln:844)]
balanceOf[FEGstakeV2 (ln:845)]
div[FEGstakeV2 (ln:848)]
mul[FEGstakeV2 (ln:848)]
sub[FEGstakeV2 (ln:849)]
balanceOf[FEGstakeV2 (ln:850)]
addStakeholder[FEGstakeV2 (ln:851)]
isStakeholder[FEGstakeV2 (ln:674)]
calcPoolOutGivenSingleIn[FEGstakeV2 (ln:872)]
bmul[FEGstakeV2 (ln:874)]
bmul[FEGstakeV2 (ln:876)]
transferFrom[FEGstakeV2 (ln:881)]
_mint[FEGstakeV2 (ln:882)]
transfer[FEGstakeV2 (ln:883)]
STAKED[FEGstakeV2 (ln:885)]
File 1 of 2: FEGstakeV2
File 2 of 2: FEG
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.7.6; abstract contract ReentrancyGuard { uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor () { _status = _NOT_ENTERED; } modifier nonReentrant() { require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); _status = _ENTERED; _; _status = _NOT_ENTERED; } } // ---------------------------------------------------------------------------- // SafeMath library // ---------------------------------------------------------------------------- library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } /** * @dev Returns the integer division of two unsigned integers. Reverts with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } function ceil(uint a, uint m) internal pure returns (uint r) { return (a + m - 1) / m * m; } } // ---------------------------------------------------------------------------- // Owned contract // ---------------------------------------------------------------------------- contract Owned { address public owner; event OwnershipTransferred(address indexed _from, address indexed _to); constructor() { owner = msg.sender; } modifier onlyOwner { require(msg.sender == owner); _; } function transferOwnership(address payable _newOwner) public onlyOwner { require(_newOwner != address(0), "ERC20: sending to the zero address"); owner = _newOwner; emit OwnershipTransferred(msg.sender, _newOwner); } } // ---------------------------------------------------------------------------- // ERC Token Standard #20 Interface // ---------------------------------------------------------------------------- interface IERC20 { function totalSupply() external view returns (uint256); function balanceOf(address tokenOwner) external view returns (uint256 balance); function allowance(address tokenOwner, address spender) external view returns (uint256 remaining); function transfer(address to, uint256 tokens) external returns (bool success); function approve(address spender, uint256 tokens) external returns (bool success); function transferFrom(address from, address to, uint256 tokens) external returns (bool success); function burnTokens(uint256 _amount) external; function calculateFeesBeforeSend( address sender, address recipient, uint256 amount ) external view returns (uint256, uint256); event Transfer(address indexed from, address indexed to, uint256 tokens); event Approval(address indexed tokenOwner, address indexed spender, uint256 tokens); } interface regreward { function distributeV2() external; } interface FEGex2 { function BUY( address to, uint minAmountOut ) external payable returns (uint tokenAmountOut, uint spotPriceAfter); } // ---------------------------------------------------------------------------- // ERC20 Token, with the addition of symbol, name and decimals and assisted // token transfers // ---------------------------------------------------------------------------- library Roles { struct Role { mapping (address => bool) bearer; } function add(Role storage role, address account) internal { require(!has(role, account), "Roles: account already has role"); role.bearer[account] = true; } function remove(Role storage role, address account) internal { require(has(role, account), "Roles: account does not have role"); role.bearer[account] = false; } function has(Role storage role, address account) internal view returns (bool) { require(account != address(0), "Roles: account is the zero address"); return role.bearer[account]; } } contract WhitelistAdminRole is Owned { using Roles for Roles.Role; event WhitelistAdminAdded(address indexed account); event WhitelistAdminRemoved(address indexed account); Roles.Role private _whitelistAdmins; constructor () { _addWhitelistAdmin(msg.sender); } modifier onlyWhitelistAdmin() { require(isWhitelistAdmin(msg.sender), "WhitelistAdminRole: caller does not have the WhitelistAdmin role"); _; } function isWhitelistAdmin(address account) public view returns (bool) { return _whitelistAdmins.has(account); } function addWhitelistAdmin(address account) public onlyWhitelistAdmin { _addWhitelistAdmin(account); } function renounceWhitelistAdmin() public { _removeWhitelistAdmin(msg.sender); } function _addWhitelistAdmin(address account) internal { _whitelistAdmins.add(account); emit WhitelistAdminAdded(account); } function _removeWhitelistAdmin(address account) internal { _whitelistAdmins.remove(account); emit WhitelistAdminRemoved(account); } } contract FNum is ReentrancyGuard{ uint public constant BASE = 10**18; function badd(uint a, uint b) internal pure returns (uint) { uint c = a + b; require(c >= a, "ERR_ADD_OVERFLOW"); return c; } function bsub(uint a, uint b) internal pure returns (uint) { (uint c, bool flag) = bsubSign(a, b); require(!flag, "ERR_SUB_UNDERFLOW"); return c; } function bsubSign(uint a, uint b) internal pure returns (uint, bool) { if (a >= b) { return (a - b, false); } else { return (b - a, true); } } function bmul(uint a, uint b) internal pure returns (uint) { uint c0 = a * b; require(a == 0 || c0 / a == b, "ERR_MUL_OVERFLOW"); uint c1 = c0 + (BASE / 2); require(c1 >= c0, "ERR_MUL_OVERFLOW"); uint c2 = c1 / BASE; return c2; } function bdiv(uint a, uint b) internal pure returns (uint) { require(b != 0, "ERR_DIV_ZERO"); uint c0 = a * BASE; require(a == 0 || c0 / a == BASE, "ERR_DIV_INTERNAL"); // bmul overflow uint c1 = c0 + (b / 2); require(c1 >= c0, "ERR_DIV_INTERNAL"); // badd require uint c2 = c1 / b; return c2; } function btoi(uint a) internal pure returns (uint) { return a / BASE; } function bfloor(uint a) internal pure returns (uint) { return btoi(a) * BASE; } function bpowi(uint a, uint n) internal pure returns (uint) { uint z = n % 2 != 0 ? a : BASE; for (n /= 2; n != 0; n /= 2) { a = bmul(a, a); if (n % 2 != 0) { z = bmul(z, a); } } return z; } function bpow(uint base, uint exp) internal pure returns (uint) { uint whole = bfloor(exp); uint remain = bsub(exp, whole); uint wholePow = bpowi(base, btoi(whole)); if (remain == 0) { return wholePow; } uint BPOW_PRECISION = BASE / 10**10; uint partialResult = bpowApprox(base, remain, BPOW_PRECISION); return bmul(wholePow, partialResult); } function bpowApprox(uint base, uint exp, uint precision) internal pure returns (uint) { // term 0: uint a = exp; (uint x, bool xneg) = bsubSign(base, BASE); uint term = BASE; uint sum = term; bool negative = false; for (uint i = 1; term >= precision; i++) { uint bigK = i * BASE; (uint c, bool cneg) = bsubSign(a, bsub(bigK, BASE)); term = bmul(term, bmul(c, x)); term = bdiv(term, bigK); if (term == 0) break; if (xneg) negative = !negative; if (cneg) negative = !negative; if (negative) { sum = bsub(sum, term); } else { sum = badd(sum, term); } } return sum; } } contract FTokenBase is FNum { mapping(address => uint) internal _balance; mapping(address => mapping(address=>uint)) internal _allowance; uint public _totalSupply; event Approval(address indexed src, address indexed dst, uint amt); event Transfer(address indexed src, address indexed dst, uint amt); function _mint(uint amt) internal { _balance[address(this)] = badd(_balance[address(this)], amt); _totalSupply = badd(_totalSupply, amt); emit Transfer(address(0), address(this), amt); } function _burn(uint amt) internal { require(_balance[address(this)] >= amt); _balance[address(this)] = bsub(_balance[address(this)], amt); _totalSupply = bsub(_totalSupply, amt); emit Transfer(address(this), address(0), amt); } function _move(address src, address dst, uint amt) internal { require(_balance[src] >= amt); _balance[src] = bsub(_balance[src], amt); _balance[dst] = badd(_balance[dst], amt); emit Transfer(src, dst, amt); } function _push(address to, uint amt) internal { _move(address(this), to, amt); } function _pull(address from, uint amt) internal { _move(from, address(this), amt); } } contract FToken is FTokenBase { string private _name = "FEG Stake Shares"; string private _symbol = "FSS"; uint8 private _decimals = 18; function name() public view returns (string memory) { return _name; } function symbol() public view returns (string memory) { return _symbol; } function decimals() public view returns(uint8) { return _decimals; } function allowance(address src, address dst) external view returns (uint) { return _allowance[src][dst]; } function balanceOf(address whom) external view returns (uint) { return _balance[whom]; } function totalSupply() public view returns (uint) { return _totalSupply; } function approve(address dst, uint amt) external returns (bool) { _allowance[msg.sender][dst] = amt; emit Approval(msg.sender, dst, amt); return true; } function increaseApproval(address dst, uint amt) external returns (bool) { _allowance[msg.sender][dst] = badd(_allowance[msg.sender][dst], amt); emit Approval(msg.sender, dst, _allowance[msg.sender][dst]); return true; } function decreaseApproval(address dst, uint amt) external returns (bool) { uint oldValue = _allowance[msg.sender][dst]; if (amt > oldValue) { _allowance[msg.sender][dst] = 0; } else { _allowance[msg.sender][dst] = bsub(oldValue, amt); } emit Approval(msg.sender, dst, _allowance[msg.sender][dst]); return true; } function transfer(address dst, uint amt) external returns (bool) { _move(msg.sender, dst, amt); return true; } function transferFrom(address src, address dst, uint amt) external returns (bool) { require(msg.sender == src || amt <= _allowance[src][msg.sender]); _move(src, dst, amt); if (msg.sender != src && _allowance[src][msg.sender] != uint256(-1)) { _allowance[src][msg.sender] = bsub(_allowance[src][msg.sender], amt); emit Approval(msg.sender, dst, _allowance[src][msg.sender]); } return true; } } contract FEGstakeV2 is Owned, ReentrancyGuard, WhitelistAdminRole, FNum, FTokenBase, FToken{ using SafeMath for uint256; address public FEG = 0x389999216860AB8E0175387A0c90E5c52522C945; address public fETH = 0xf786c34106762Ab4Eeb45a51B42a62470E9D5332; address public USDT = 0x979838c9C16FD365C9fE028B0bEa49B1750d86e9; address public TRY = 0xc12eCeE46ed65D970EE5C899FCC7AE133AfF9b03; address public FETP = 0xa40462266dC28dB1d570FC8F8a0F4B72B8618f7a; address public BTC = 0xe3cDB92b094a3BeF3f16103b53bECfb17A3558ad; address public poolShares = address(this); address public regrewardContract; //Signs The Checks bool public live = false; bool public perform = false; //if true then distribution of rewards from the pool to stakers via the withdraw function is enabled bool public perform2 = true; //if true then distribution of TX rewards from unclaimed 1 and 2 wrap's will distribute to stakers bool public perform3 = true; //if true then distribution of TX rewards from unclaimed 3rd wrap's will distribute to stakers uint256 public scailment = 20; // FEG has TX fee, deduct this fee to not break maths uint256 public totalDividends = 0; uint256 public must = 3e15; uint256 public scaleatize = 99; uint256 private scaledRemainder = 0; uint256 private scaling = uint256(10) ** 12; uint public round = 1; uint256 public totalDividends1 = 0; uint256 private scaledRemainder1 = 0; uint256 private scaling1 = uint256(10) ** 12; uint public round1 = 1; uint256 public totalDividends2 = 0; uint256 private scaledRemainder2 = 0; uint256 private scaling2 = uint256(10) ** 12; uint public round2 = 1; mapping(address => uint) public farmTime; // When you staked struct USER{ uint256 lastDividends; uint256 fromTotalDividend; uint round; uint256 remainder; uint256 lastDividends1; uint256 fromTotalDividend1; uint round1; uint256 remainder1; uint256 lastDividends2; uint256 fromTotalDividend2; uint round2; uint256 remainder2; bool initialized; bool activated; } address[] internal stakeholders; uint public scalerize = 98; uint256 public scaletor = 1e17; uint256 public scaletor1 = 20e18; uint256 public scaletor2 = 1e15; uint256 public totalWrap; // total unclaimed fETH rewards uint256 public totalWrap1; // total unclaimed usdt rewards uint256 public totalWrap2; // total unclaimed btc rewards uint256 public totalWrapRef = bsub(IERC20(fETH).balanceOf(address(this)), totalWrap); //total fETH reflections unclaimed uint256 public totalWrapRef1 = bsub(IERC20(USDT).balanceOf(address(this)), totalWrap1); //total usdt reflections unclaimed uint256 public totalWrapRef2 = bsub(IERC20(BTC).balanceOf(address(this)), totalWrap2); //total BTC reflections unclaimed mapping(address => USER) stakers; mapping (uint => uint256) public payouts; // keeps record of each payout mapping (uint => uint256) public payouts1; // keeps record of each payout mapping (uint => uint256) public payouts2; // keeps record of each payout FEGex2 fegexpair; event STAKED(address staker, uint256 tokens); event ACTIVATED(address staker, uint256 cost); event START(address staker, uint256 tokens); event EARNED(address staker, uint256 tokens); event UNSTAKED(address staker, uint256 tokens); event PAYOUT(uint256 round, uint256 tokens, address sender); event PAYOUT1(uint256 round, uint256 tokens, address sender); event PAYOUT2(uint256 round, uint256 tokens, address sender); event CLAIMEDREWARD(address staker, uint256 reward); event CLAIMEDREWARD1(address staker, uint256 reward); event CLAIMEDREWARD2(address staker, uint256 reward); constructor(){ fegexpair = FEGex2(FETP); } receive() external payable { } function changeFEGExPair(FEGex2 _fegexpair, address addy) external onlyOwner{ // Incase FEGex updates in future require(address(_fegexpair) != address(0), "setting 0 to contract"); fegexpair = _fegexpair; FETP = addy; } function changeTRY(address _try) external onlyOwner{ // Incase TRY updates in future TRY = _try; } function changeScalerize(uint _sca) public onlyOwner{ require(_sca != 0, "You cannot turn off"); scalerize = _sca; } function changeScalatize(uint _scm) public onlyOwner { require(_scm != 0, "You cannot turn off"); scaleatize = _scm; } function isStakeholder(address _address) public view returns(bool) { if(stakers[_address].initialized) return true; else return false; } function addStakeholder(address _stakeholder) internal { (bool _isStakeholder) = isStakeholder(_stakeholder); if(!_isStakeholder) { farmTime[msg.sender] = block.timestamp; stakers[_stakeholder].initialized = true; } } // ------------------------------------------------------------------------ // Token holders can stake their tokens using this function // @param tokens number of tokens to stake // ------------------------------------------------------------------------ function calcPoolInGivenSingleOut( uint tokenBalanceOut, uint tokenWeightOut, uint poolSupply, uint totalWeight, uint tokenAmountOut, uint swapFee ) public pure returns (uint poolAmountIn) { uint normalizedWeight = bdiv(tokenWeightOut, totalWeight); uint zar = bmul(bsub(BASE, normalizedWeight), swapFee); uint tokenAmountOutBeforeSwapFee = bdiv(tokenAmountOut, bsub(BASE, zar)); uint newTokenBalanceOut = bsub(tokenBalanceOut, tokenAmountOutBeforeSwapFee); uint tokenOutRatio = bdiv(newTokenBalanceOut, tokenBalanceOut); uint poolRatio = bpow(tokenOutRatio, normalizedWeight); uint newPoolSupply = bmul(poolRatio, poolSupply); uint poolAmountInAfterExitFee = bsub(poolSupply, newPoolSupply); poolAmountIn = bdiv(poolAmountInAfterExitFee, bsub(BASE, 0)); return (poolAmountIn); } function calcSingleOutGivenPoolIn( uint tokenBalanceOut, uint tokenWeightOut, uint poolSupply, uint totalWeight, uint poolAmountIn, uint swapFee ) public pure returns (uint tokenAmountOut) { uint normalizedWeight = bdiv(tokenWeightOut, totalWeight); uint poolAmountInAfterExitFee = bmul(poolAmountIn, bsub(BASE, 0)); uint newPoolSupply = bsub(poolSupply, poolAmountInAfterExitFee); uint poolRatio = bdiv(newPoolSupply, poolSupply); uint tokenOutRatio = bpow(poolRatio, bdiv(BASE, normalizedWeight)); uint newTokenBalanceOut = bmul(tokenOutRatio, tokenBalanceOut); uint tokenAmountOutBeforeSwapFee = bsub(tokenBalanceOut, newTokenBalanceOut); uint zaz = bmul(bsub(BASE, normalizedWeight), swapFee); tokenAmountOut = bmul(tokenAmountOutBeforeSwapFee, bsub(BASE, zaz)); return tokenAmountOut; } function calcPoolOutGivenSingleIn( uint tokenBalanceIn, uint tokenWeightIn, uint poolSupply, uint totalWeight, uint tokenAmountIn, uint swapFee ) public pure returns (uint poolAmountOut) { uint normalizedWeight = bdiv(tokenWeightIn, totalWeight); uint zaz = bmul(bsub(BASE, normalizedWeight), swapFee); uint tokenAmountInAfterFee = bmul(tokenAmountIn, bsub(BASE, zaz)); uint newTokenBalanceIn = badd(tokenBalanceIn, tokenAmountInAfterFee); uint tokenInRatio = bdiv(newTokenBalanceIn, tokenBalanceIn); uint poolRatio = bpow(tokenInRatio, normalizedWeight); uint newPoolSupply = bmul(poolRatio, poolSupply); poolAmountOut = bsub(newPoolSupply, poolSupply); return (poolAmountOut); } function calcOutGivenIn( uint tokenBalanceIn, uint tokenWeightIn, uint tokenBalanceOut, uint tokenWeightOut, uint tokenAmountIn, uint swapFee ) public pure returns (uint tokenAmountOut, uint tokenInFee) { uint weightRatio = bdiv(tokenWeightIn, tokenWeightOut); uint adjustedIn = bsub(BASE, swapFee); adjustedIn = bmul(tokenAmountIn, adjustedIn); uint y = bdiv(tokenBalanceIn, badd(tokenBalanceIn, adjustedIn)); uint foo = bpow(y, weightRatio); uint bar = bsub(BASE, foo); tokenAmountOut = bmul(tokenBalanceOut, bar); tokenInFee = bsub(tokenAmountIn, adjustedIn); return (tokenAmountOut, tokenInFee); } function calcInGivenOut( uint tokenBalanceIn, uint tokenWeightIn, uint tokenBalanceOut, uint tokenWeightOut, uint tokenAmountOut, uint swapFee ) public pure returns (uint tokenAmountIn) { uint weightRatio = bdiv(tokenWeightOut, tokenWeightIn); uint diff = bsub(tokenBalanceOut, tokenAmountOut); uint y = bdiv(tokenBalanceOut, diff); uint foo = bpow(y, weightRatio); foo = bsub(foo, BASE); foo = bmul(tokenBalanceIn, foo); tokenAmountIn = bsub(BASE, swapFee); tokenAmountIn = bdiv(foo, tokenAmountIn); return (tokenAmountIn); } function activateUserStaking() public payable{ // Activation of FEGstake costs 0.02 fETH which is automatically refunded to your wallet in the form of TRY. require(msg.value == must, "You must deposit the right amount to activate"); fegexpair.BUY{value: msg.value }(msg.sender, 100); stakers[msg.sender].activated = true; emit ACTIVATED(msg.sender, msg.value); } function isActivated(address staker) public view returns(bool){ if(stakers[staker].activated) return true; else return false; } function Start(uint256 tokens) public onlyOwner returns(uint poolAmountOut){ require(live == false, "Can only use once"); require(IERC20(FEG).transferFrom(msg.sender, address(this), tokens), "Tokens cannot be transferred from user for locking"); uint256 transferTxFee = (onePercent(tokens).mul(scailment)).div(10); uint256 tokensToStake = (tokens.sub(transferTxFee)); addStakeholder(msg.sender); _mint(tokensToStake); live = true; IERC20(poolShares).transfer(msg.sender, tokensToStake); IERC20(address(fETH)).approve(address(FETP), 1000000000000000000000e18); emit START(msg.sender, tokensToStake); return poolAmountOut; } function STAKE(uint256 tokens) public returns(uint poolAmountOut){ require(IERC20(FEG).balanceOf(msg.sender) >= tokens, "You do not have enough FEG"); require(stakers[msg.sender].activated == true); require(live == true); uint256 transferTxFee = (onePercent(tokens).mul(scailment)).div(10); uint256 tokensToStake = (tokens.sub(transferTxFee)); uint256 totalFEG = IERC20(FEG).balanceOf(address(this)); addStakeholder(msg.sender); // add pending rewards to remainder to be claimed by user later, if there is any existing stake uint256 owing = pendingReward(msg.sender); stakers[msg.sender].remainder += owing; stakers[msg.sender].lastDividends = owing; stakers[msg.sender].fromTotalDividend = totalDividends; stakers[msg.sender].round = round; uint256 owing1 = pendingReward1(msg.sender); stakers[msg.sender].remainder1 += owing1; stakers[msg.sender].lastDividends1 = owing1; stakers[msg.sender].fromTotalDividend1 = totalDividends1; stakers[msg.sender].round1 = round1; uint256 owing2 = pendingReward2(msg.sender); stakers[msg.sender].remainder2 += owing2; stakers[msg.sender].lastDividends2 = owing2; stakers[msg.sender].fromTotalDividend2 = totalDividends2; stakers[msg.sender].round2 = round2; poolAmountOut = calcPoolOutGivenSingleIn( totalFEG, bmul(BASE, 25), _totalSupply, bmul(BASE, 25), tokensToStake, 0 ); require(IERC20(FEG).transferFrom(msg.sender, address(this), tokens), "Tokens cannot be transferred from user for locking"); _mint(poolAmountOut); IERC20(poolShares).transfer(msg.sender, poolAmountOut); emit STAKED(msg.sender, tokens); return poolAmountOut; } // ------------------------------------------------------------------------ // Owners can send the funds to be distributed to stakers using this function // @param tokens number of tokens to distribute // ------------------------------------------------------------------------ function ADDFUNDS1(uint256 tokens) public onlyWhitelistAdmin{ require(IERC20(fETH).transferFrom(msg.sender, address(this), tokens), "Tokens cannot be transferred from funder account"); uint256 tokens_ = bmul(tokens, bdiv(99, 100)); totalWrap = badd(totalWrap, tokens_); _addPayout(tokens_); } function ADDFUNDS2(uint256 tokens) public onlyWhitelistAdmin{ require(IERC20(USDT).transferFrom(msg.sender, address(this), tokens), "Tokens cannot be transferred from funder account"); uint256 tokens_ = bmul(tokens, bdiv(99, 100)); totalWrap1 = badd(totalWrap1, tokens_); _addPayout1(tokens_); } function ADDFUNDS3(uint256 tokens) public onlyWhitelistAdmin{ require(IERC20(BTC).transferFrom(msg.sender, address(this), tokens), "Tokens cannot be transferred from funder account"); uint256 tokens_ = bmul(tokens, bdiv(99, 100)); totalWrap2 = badd(totalWrap2, tokens_); _addPayout2(tokens_); } // ------------------------------------------------------------------------ // Private function to register payouts // ------------------------------------------------------------------------ function _addPayout(uint256 tokens_) private { // divide the funds among the currently staked tokens // scale the deposit and add the previous remainder uint256 totalShares = _totalSupply; uint256 available = (tokens_.mul(scaling)).add(scaledRemainder); uint256 dividendPerToken = available.div(totalShares); scaledRemainder = available.mod(totalShares); totalDividends = totalDividends.add(dividendPerToken); payouts[round] = payouts[round - 1].add(dividendPerToken); emit PAYOUT(round, tokens_, msg.sender); round++; } function _addPayout1(uint256 tokens_1) private{ // divide the funds among the currently staked tokens // scale the deposit and add the previous remainder uint256 totalShares = _totalSupply; uint256 available = (tokens_1.mul(scaling)).add(scaledRemainder1); uint256 dividendPerToken = available.div(totalShares); scaledRemainder1 = available.mod(totalShares); totalDividends1 = totalDividends1.add(dividendPerToken); payouts1[round1] = payouts1[round1 - 1].add(dividendPerToken); emit PAYOUT1(round1, tokens_1, msg.sender); round1++; } function _addPayout2(uint256 tokens_2) private{ // divide the funds among the currently staked tokens // scale the deposit and add the previous remainder uint256 totalShares = _totalSupply; uint256 available = (tokens_2.mul(scaling)).add(scaledRemainder2); uint256 dividendPerToken = available.div(totalShares); scaledRemainder2 = available.mod(totalShares); totalDividends2 = totalDividends2.add(dividendPerToken); payouts2[round2] = payouts2[round2 - 1].add(dividendPerToken); emit PAYOUT2(round2, tokens_2, msg.sender); round2++; } // ------------------------------------------------------------------------ // Stakers can claim their pending rewards using this function // ------------------------------------------------------------------------ function CLAIMREWARD() public nonReentrant{ uint256 owing = pendingReward(msg.sender); if(owing > 0){ owing = owing.add(stakers[msg.sender].remainder); stakers[msg.sender].remainder = 0; require(IERC20(fETH).transfer(msg.sender,owing), "ERROR: error in sending reward from contract"); emit CLAIMEDREWARD(msg.sender, owing); totalWrap = bsub(totalWrap, owing); stakers[msg.sender].lastDividends = owing; // unscaled stakers[msg.sender].round = round; // update the round stakers[msg.sender].fromTotalDividend = totalDividends; // scaled } } function CLAIMREWARD1() public nonReentrant { uint256 owing1 = pendingReward1(msg.sender); if(owing1 > 0){ owing1 = owing1.add(stakers[msg.sender].remainder1); stakers[msg.sender].remainder1 = 0; require(IERC20(USDT).transfer(msg.sender,owing1), "ERROR: error in sending reward from contract"); emit CLAIMEDREWARD1(msg.sender, owing1); totalWrap1 = bsub(totalWrap1, owing1); stakers[msg.sender].lastDividends1 = owing1; // unscaled stakers[msg.sender].round1 = round1; // update the round stakers[msg.sender].fromTotalDividend1 = totalDividends1; // scaled } } function CLAIMREWARD2() public nonReentrant { uint256 owing2 = pendingReward2(msg.sender); if(owing2 > 0){ owing2 = owing2.add(stakers[msg.sender].remainder2); stakers[msg.sender].remainder2 = 0; require(IERC20(BTC).transfer(msg.sender, owing2), "ERROR: error in sending reward from contract"); emit CLAIMEDREWARD2(msg.sender, owing2); totalWrap2 = bsub(totalWrap2, owing2); stakers[msg.sender].lastDividends2 = owing2; // unscaled stakers[msg.sender].round2 = round2; // update the round stakers[msg.sender].fromTotalDividend2 = totalDividends2; // scaled } } function CLAIMALLREWARD() public { distribute12(); CLAIMREWARD(); CLAIMREWARD1(); if(perform3==true){ distribute23(); CLAIMREWARD2(); } } // ------------------------------------------------------------------------ // Get the pending rewards of the staker // @param _staker the address of the staker // ------------------------------------------------------------------------ function pendingReward(address staker) private returns (uint256) { require(staker != address(0), "ERC20: sending to the zero address"); uint256 yourBase = IERC20(poolShares).balanceOf(msg.sender); uint stakersRound = stakers[staker].round; uint256 amount = ((totalDividends.sub(payouts[stakersRound - 1])).mul(yourBase)).div(scaling); stakers[staker].remainder += ((totalDividends.sub(payouts[stakersRound - 1])).mul(yourBase)) % scaling; return (bmul(amount, bdiv(scalerize, 100))); } function pendingReward1(address staker) private returns (uint256) { require(staker != address(0), "ERC20: sending to the zero address"); uint256 yourBase = IERC20(poolShares).balanceOf(msg.sender); uint stakersRound = stakers[staker].round1; uint256 amount1 = ((totalDividends1.sub(payouts1[stakersRound - 1])).mul(yourBase)).div(scaling); stakers[staker].remainder1 += ((totalDividends1.sub(payouts1[stakersRound - 1])).mul(yourBase)) % scaling; return (bmul(amount1, bdiv(scalerize, 100))); } function pendingReward2(address staker) private returns (uint256) { require(staker != address(0), "ERC20: sending to the zero address"); uint256 yourBase = IERC20(poolShares).balanceOf(msg.sender); uint stakersRound = stakers[staker].round2; uint256 amount2 = ((totalDividends2.sub(payouts2[stakersRound - 1])).mul(yourBase)).div(scaling); stakers[staker].remainder2 += ((totalDividends2.sub(payouts2[stakersRound - 1])).mul(yourBase)) % scaling; return (bmul(amount2, bdiv(scalerize, 100))); } function getPending1(address staker) public view returns(uint256 _pendingReward) { require(staker != address(0), "ERC20: sending to the zero address"); uint256 yourBase = IERC20(poolShares).balanceOf(staker); uint stakersRound = stakers[staker].round; uint256 amount = ((totalDividends.sub(payouts[stakersRound - 1])).mul(yourBase)).div(scaling); amount += ((totalDividends.sub(payouts[stakersRound - 1])).mul(yourBase)) % scaling; return (bmul(amount.add(stakers[staker].remainder), bdiv(scalerize, 100))); } function getPending2(address staker) public view returns(uint256 _pendingReward) { require(staker != address(0), "ERC20: sending to the zero address"); uint256 yourBase = IERC20(poolShares).balanceOf(staker); uint stakersRound = stakers[staker].round1; uint256 amount1 = ((totalDividends1.sub(payouts1[stakersRound - 1])).mul(yourBase)).div(scaling); amount1 += ((totalDividends1.sub(payouts1[stakersRound - 1])).mul(yourBase)) % scaling; return (bmul(amount1.add(stakers[staker].remainder1), bdiv(scalerize, 100))); } function getPending3(address staker) public view returns(uint256 _pendingReward) { require(staker != address(0), "ERC20: sending to the zero address"); uint256 yourBase = IERC20(poolShares).balanceOf(staker); uint stakersRound = stakers[staker].round2; uint256 amount2 = ((totalDividends2.sub(payouts2[stakersRound - 1])).mul(yourBase)).div(scaling); amount2 += ((totalDividends2.sub(payouts2[stakersRound - 1])).mul(yourBase)) % scaling; return (bmul(amount2.add(stakers[staker].remainder2), bdiv(scalerize, 100))); } // ------------------------------------------------------------------------ // Get the FEG balance of the token holder // @param user the address of the token holder // ------------------------------------------------------------------------ function userStakedFEG(address user) external view returns(uint256 StakedFEG){ require(user != address(0), "ERC20: sending to the zero address"); uint256 totalFEG = IERC20(FEG).balanceOf(address(this)); uint256 yourStakedFEG = calcSingleOutGivenPoolIn( totalFEG, bmul(BASE, 25), _totalSupply, bmul(BASE, 25), IERC20(poolShares).balanceOf(address(user)), 0 ); return yourStakedFEG; } // ------------------------------------------------------------------------ // Stakers can un stake the staked tokens using this function // @param tokens the number of tokens to withdraw // ------------------------------------------------------------------------ function WITHDRAW(address to, uint256 _tokens) external returns (uint tokenAmountOut) { uint256 totalFEG = IERC20(FEG).balanceOf(address(this)); require(stakers[msg.sender].activated == true); if(perform==true) { regreward(regrewardContract).distributeV2(); } CLAIMALLREWARD(); uint256 tokens = calcPoolInGivenSingleOut( totalFEG, bmul(BASE, 25), _totalSupply, bmul(BASE, 25), _tokens, 0 ); tokenAmountOut = calcSingleOutGivenPoolIn( totalFEG, bmul(BASE, 25), _totalSupply, bmul(BASE, 25), tokens, 0 ); require(tokens <= IERC20(poolShares).balanceOf(msg.sender), "You don't have enough FEG"); _pullPoolShare(tokens); _burn(tokens); require(IERC20(FEG).transfer(to, tokenAmountOut), "Error in un-staking tokens"); emit UNSTAKED(msg.sender, tokens); return tokenAmountOut; } function _pullPoolShare(uint amount) internal { bool xfer = IERC20(poolShares).transferFrom(msg.sender, address(this), amount); require(xfer, "ERR_ERC20_FALSE"); } // ------------------------------------------------------------------------ // Private function to calculate 1% percentage // ------------------------------------------------------------------------ function onePercent(uint256 _tokens) private pure returns (uint256){ uint256 roundValue = _tokens.ceil(100); uint onePercentofTokens = roundValue.mul(100).div(100 * 10**uint(2)); return onePercentofTokens; } function emergencySaveLostTokens(address to, address _token, uint256 _amt) public onlyOwner { require(_token != FEG, "Cannot remove users FEG"); require(_token != fETH, "Cannot remove users fETH"); require(_token != USDT, "Cannot remove users fUSDT"); require(_token != BTC, "Cannot remove users fBTC"); require(IERC20(_token).transfer(to, _amt), "Error in retrieving tokens"); payable(owner).transfer(address(this).balance); } function changeregrewardContract(address _regrewardContract) external onlyOwner{ require(address(_regrewardContract) != address(0), "setting 0 to contract"); regrewardContract = _regrewardContract; } function changePerform(bool _bool) external onlyOwner{ perform = _bool; } function changePerform2(bool _bool) external onlyOwner{ perform2 = _bool; } function changePerform3(bool _bool) external onlyOwner{ perform3 = _bool; } function changeMust(uint256 _must) external onlyOwner{ require(must !=0, "Cannot set to 0"); require(must <= 3e15, "Cannot set over 0.003 fETH"); must = _must; } function updateBase(address _BTC, address _ETH, address _USDT) external onlyOwner{ // Incase wraps ever update BTC = _BTC; fETH = _ETH; USDT = _USDT; } function distribute12() public { if (IERC20(fETH).balanceOf(address(this)) > badd(totalWrap, scaletor)) { distributeWrap1(); } if(IERC20(USDT).balanceOf(address(this)) > badd(totalWrap1, scaletor1)){ distributeWrap2(); } } function distribute23() public { if(perform3==true){ if(IERC20(BTC).balanceOf(address(this)) > badd(totalWrap2, scaletor2)){ distributeWrap3();} } } function changeScaletor(uint256 _sca, uint256 _sca1, uint256 _sca2) public onlyOwner { require(_sca !=0 && _sca1 !=0 && _sca2 !=0, "You cannot turn off"); require(_sca >= 5e17 && _sca1 >= 20e18 && _sca2 >= 1e15, "Must be over minimum"); scaletor = _sca; scaletor1 = _sca1; scaletor2 = _sca2; } function distributeWrap1() internal { uint256 wrapped = bsub(IERC20(fETH).balanceOf(address(this)), totalWrap); totalWrap = badd(totalWrap, wrapped); _addPayout(wrapped); } function distributeWrap2() internal { uint256 wrapped = bsub(IERC20(USDT).balanceOf(address(this)), totalWrap1); totalWrap1 = badd(totalWrap1, wrapped); _addPayout1(wrapped); } function distributeWrap3() internal { uint256 wrapped = bsub(IERC20(BTC).balanceOf(address(this)), totalWrap2); totalWrap2 = badd(totalWrap2, wrapped); _addPayout2(wrapped); } }
File 2 of 2: FEG
// FEG (Fuck Emily Goetz Token) // Why? Because fuck you thats why! // The best way to say FUCK YOU EMILY GOETZ is to blow up a token with her code with FEG as the ticker! // Why 100,000,000,000,000,000 token supply? That's how many times she's had VD! hahaha Fuck Emily Goetz! // SPDX-License-Identifier: Unlicensed pragma solidity ^0.6.12; abstract contract Context { function _msgSender() internal view virtual returns (address payable) { return msg.sender; } function _msgData() internal view virtual returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } } interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); } library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } /** * @dev Returns the integer division of two unsigned integers. Reverts with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } } 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) { // According to EIP-1052, 0x0 is the value returned for not-yet created accounts // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned // for accounts without code, i.e. `keccak256('')` bytes32 codehash; bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; // solhint-disable-next-line no-inline-assembly assembly { codehash := extcodehash(account) } return (codehash != accountHash && codehash != 0x0); } /** * @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"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (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"); return _functionCallWithValue(target, data, value, errorMessage); } function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) { require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: weiValue }(data); 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 // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } 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 () internal { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the current owner. */ function owner() public view 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 { emit OwnershipTransferred(_owner, address(0)); _owner = 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"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } } contract FEG is Context, IERC20, Ownable { using SafeMath for uint256; using Address for address; mapping (address => uint256) private _rOwned; mapping (address => uint256) private _tOwned; mapping (address => mapping (address => uint256)) private _allowances; mapping (address => bool) private _isExcluded; address[] private _excluded; uint256 private constant MAX = ~uint256(0); uint256 private constant _tTotal = 100000000000 * 10**6 * 10**9; uint256 private _rTotal = (MAX - (MAX % _tTotal)); uint256 private _tFeeTotal; string private _name = 'FEGtoken'; string private _symbol = 'FEG'; uint8 private _decimals = 9; constructor () public { _rOwned[_msgSender()] = _rTotal; emit Transfer(address(0), _msgSender(), _tTotal); } function name() public view returns (string memory) { return _name; } function symbol() public view returns (string memory) { return _symbol; } function decimals() public view returns (uint8) { return _decimals; } function totalSupply() public view override returns (uint256) { return _tTotal; } function balanceOf(address account) public view override returns (uint256) { if (_isExcluded[account]) return _tOwned[account]; return tokenFromReflection(_rOwned[account]); } function transfer(address recipient, uint256 amount) public override returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } function allowance(address owner, address spender) public view override returns (uint256) { return _allowances[owner][spender]; } function approve(address spender, uint256 amount) public override returns (bool) { _approve(_msgSender(), spender, amount); return true; } function transferFrom(address sender, address recipient, uint256 amount) public override returns (bool) { _transfer(sender, recipient, amount); _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance")); return true; } function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue)); return true; } function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero")); return true; } function isExcluded(address account) public view returns (bool) { return _isExcluded[account]; } function totalFees() public view returns (uint256) { return _tFeeTotal; } function reflect(uint256 tAmount) public { address sender = _msgSender(); require(!_isExcluded[sender], "Excluded addresses cannot call this function"); (uint256 rAmount,,,,) = _getValues(tAmount); _rOwned[sender] = _rOwned[sender].sub(rAmount); _rTotal = _rTotal.sub(rAmount); _tFeeTotal = _tFeeTotal.add(tAmount); } function reflectionFromToken(uint256 tAmount, bool deductTransferFee) public view returns(uint256) { require(tAmount <= _tTotal, "Amount must be less than supply"); if (!deductTransferFee) { (uint256 rAmount,,,,) = _getValues(tAmount); return rAmount; } else { (,uint256 rTransferAmount,,,) = _getValues(tAmount); return rTransferAmount; } } function tokenFromReflection(uint256 rAmount) public view returns(uint256) { require(rAmount <= _rTotal, "Amount must be less than total reflections"); uint256 currentRate = _getRate(); return rAmount.div(currentRate); } function excludeAccount(address account) external onlyOwner() { require(!_isExcluded[account], "Account is already excluded"); if(_rOwned[account] > 0) { _tOwned[account] = tokenFromReflection(_rOwned[account]); } _isExcluded[account] = true; _excluded.push(account); } function includeAccount(address account) external onlyOwner() { require(_isExcluded[account], "Account is already excluded"); for (uint256 i = 0; i < _excluded.length; i++) { if (_excluded[i] == account) { _excluded[i] = _excluded[_excluded.length - 1]; _tOwned[account] = 0; _isExcluded[account] = false; _excluded.pop(); break; } } } function _approve(address owner, address spender, uint256 amount) private { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } function _transfer(address sender, address recipient, uint256 amount) private { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); require(amount > 0, "Transfer amount must be greater than zero"); if (_isExcluded[sender] && !_isExcluded[recipient]) { _transferFromExcluded(sender, recipient, amount); } else if (!_isExcluded[sender] && _isExcluded[recipient]) { _transferToExcluded(sender, recipient, amount); } else if (!_isExcluded[sender] && !_isExcluded[recipient]) { _transferStandard(sender, recipient, amount); } else if (_isExcluded[sender] && _isExcluded[recipient]) { _transferBothExcluded(sender, recipient, amount); } else { _transferStandard(sender, recipient, amount); } } function _transferStandard(address sender, address recipient, uint256 tAmount) private { (uint256 rAmount, uint256 rTransferAmount, uint256 rFee, uint256 tTransferAmount, uint256 tFee) = _getValues(tAmount); _rOwned[sender] = _rOwned[sender].sub(rAmount); _rOwned[recipient] = _rOwned[recipient].add(rTransferAmount); _reflectFee(rFee, tFee); emit Transfer(sender, recipient, tTransferAmount); } function _transferToExcluded(address sender, address recipient, uint256 tAmount) private { (uint256 rAmount, uint256 rTransferAmount, uint256 rFee, uint256 tTransferAmount, uint256 tFee) = _getValues(tAmount); _rOwned[sender] = _rOwned[sender].sub(rAmount); _tOwned[recipient] = _tOwned[recipient].add(tTransferAmount); _rOwned[recipient] = _rOwned[recipient].add(rTransferAmount); _reflectFee(rFee, tFee); emit Transfer(sender, recipient, tTransferAmount); } function _transferFromExcluded(address sender, address recipient, uint256 tAmount) private { (uint256 rAmount, uint256 rTransferAmount, uint256 rFee, uint256 tTransferAmount, uint256 tFee) = _getValues(tAmount); _tOwned[sender] = _tOwned[sender].sub(tAmount); _rOwned[sender] = _rOwned[sender].sub(rAmount); _rOwned[recipient] = _rOwned[recipient].add(rTransferAmount); _reflectFee(rFee, tFee); emit Transfer(sender, recipient, tTransferAmount); } function _transferBothExcluded(address sender, address recipient, uint256 tAmount) private { (uint256 rAmount, uint256 rTransferAmount, uint256 rFee, uint256 tTransferAmount, uint256 tFee) = _getValues(tAmount); _tOwned[sender] = _tOwned[sender].sub(tAmount); _rOwned[sender] = _rOwned[sender].sub(rAmount); _tOwned[recipient] = _tOwned[recipient].add(tTransferAmount); _rOwned[recipient] = _rOwned[recipient].add(rTransferAmount); _reflectFee(rFee, tFee); emit Transfer(sender, recipient, tTransferAmount); } function _reflectFee(uint256 rFee, uint256 tFee) private { _rTotal = _rTotal.sub(rFee); _tFeeTotal = _tFeeTotal.add(tFee); } function _getValues(uint256 tAmount) private view returns (uint256, uint256, uint256, uint256, uint256) { (uint256 tTransferAmount, uint256 tFee) = _getTValues(tAmount); uint256 currentRate = _getRate(); (uint256 rAmount, uint256 rTransferAmount, uint256 rFee) = _getRValues(tAmount, tFee, currentRate); return (rAmount, rTransferAmount, rFee, tTransferAmount, tFee); } function _getTValues(uint256 tAmount) private pure returns (uint256, uint256) { uint256 tFee = tAmount.div(100).mul(2); uint256 tTransferAmount = tAmount.sub(tFee); return (tTransferAmount, tFee); } function _getRValues(uint256 tAmount, uint256 tFee, uint256 currentRate) private pure returns (uint256, uint256, uint256) { uint256 rAmount = tAmount.mul(currentRate); uint256 rFee = tFee.mul(currentRate); uint256 rTransferAmount = rAmount.sub(rFee); return (rAmount, rTransferAmount, rFee); } function _getRate() private view returns(uint256) { (uint256 rSupply, uint256 tSupply) = _getCurrentSupply(); return rSupply.div(tSupply); } function _getCurrentSupply() private view returns(uint256, uint256) { uint256 rSupply = _rTotal; uint256 tSupply = _tTotal; for (uint256 i = 0; i < _excluded.length; i++) { if (_rOwned[_excluded[i]] > rSupply || _tOwned[_excluded[i]] > tSupply) return (_rTotal, _tTotal); rSupply = rSupply.sub(_rOwned[_excluded[i]]); tSupply = tSupply.sub(_tOwned[_excluded[i]]); } if (rSupply < _rTotal.div(_tTotal)) return (_rTotal, _tTotal); return (rSupply, tSupply); } }