More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 3,295 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Reinvest | 21414087 | 16 days ago | IN | 0 ETH | 0.00107658 | ||||
Claim | 21414079 | 16 days ago | IN | 0 ETH | 0.00148037 | ||||
Withdraw | 21327092 | 29 days ago | IN | 0 ETH | 0.00320691 | ||||
Claim | 21191253 | 47 days ago | IN | 0 ETH | 0.00215178 | ||||
Withdraw | 21191250 | 47 days ago | IN | 0 ETH | 0.00257942 | ||||
Withdraw | 20614955 | 128 days ago | IN | 0 ETH | 0.00051399 | ||||
Claim | 20614952 | 128 days ago | IN | 0 ETH | 0.0004977 | ||||
Withdraw All | 20425685 | 154 days ago | IN | 0 ETH | 0.0000948 | ||||
Claim | 20425670 | 154 days ago | IN | 0 ETH | 0.00041428 | ||||
Withdraw | 20339679 | 166 days ago | IN | 0 ETH | 0.00080301 | ||||
Claim | 20303297 | 171 days ago | IN | 0 ETH | 0.0005939 | ||||
Withdraw | 20303291 | 171 days ago | IN | 0 ETH | 0.00071131 | ||||
Reinvest | 20144884 | 194 days ago | IN | 0 ETH | 0.00028556 | ||||
Claim | 20030029 | 210 days ago | IN | 0 ETH | 0.00177886 | ||||
Withdraw | 19903681 | 227 days ago | IN | 0 ETH | 0.00043969 | ||||
Claim | 19864377 | 233 days ago | IN | 0 ETH | 0.00097058 | ||||
Claim | 19773578 | 245 days ago | IN | 0 ETH | 0.00080439 | ||||
Withdraw | 19773571 | 245 days ago | IN | 0 ETH | 0.00143906 | ||||
Claim | 19567052 | 274 days ago | IN | 0 ETH | 0.00518374 | ||||
Withdraw | 19557440 | 276 days ago | IN | 0 ETH | 0.0033931 | ||||
Claim | 19211303 | 324 days ago | IN | 0 ETH | 0.00221963 | ||||
Withdraw | 19108274 | 339 days ago | IN | 0 ETH | 0.00162044 | ||||
Withdraw | 19006806 | 353 days ago | IN | 0 ETH | 0.00353455 | ||||
Claim | 19006802 | 353 days ago | IN | 0 ETH | 0.00421319 | ||||
Withdraw | 18967448 | 358 days ago | IN | 0 ETH | 0.00255212 |
Latest 1 internal transaction
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
13995722 | 1084 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Contract Name:
StakingRewards
Compiler Version
v0.8.11+commit.d7f03943
Contract Source Code (Solidity Multiple files format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.11; import "./WTF.sol"; import "./ERC20.sol"; import "./PRBMathUD60x18.sol"; contract StakingRewards { using PRBMathUD60x18 for uint256; uint256 constant private FLOAT_SCALAR = 2**64; uint256 constant private PERCENT_FEE = 5; // only for WTF staking uint256 constant private X_TICK = 30 days; struct User { uint256 deposited; int256 scaledPayout; } struct Info { uint256 totalRewards; uint256 startTime; uint256 lastUpdated; uint256 pendingFee; uint256 scaledRewardsPerToken; uint256 totalDeposited; mapping(address => User) users; WTF wtf; ERC20 token; } Info private info; event Deposit(address indexed user, uint256 amount, uint256 fee); event Withdraw(address indexed user, uint256 amount, uint256 fee); event Claim(address indexed user, uint256 amount); event Reinvest(address indexed user, uint256 amount); event Reward(uint256 amount); constructor(uint256 _totalRewards, uint256 _stakingRewardsStart, ERC20 _token) { info.totalRewards = _totalRewards; info.startTime = block.timestamp < _stakingRewardsStart ? _stakingRewardsStart : block.timestamp; info.lastUpdated = startTime(); info.wtf = WTF(msg.sender); info.token = _token; } function update() public { uint256 _now = block.timestamp; if (_now > info.lastUpdated && totalDeposited() > 0) { uint256 _reward = info.totalRewards.mul(_delta(_getX(info.lastUpdated), _getX(_now))); if (info.pendingFee > 0) { _reward += info.pendingFee; info.pendingFee = 0; } uint256 _balanceBefore = info.wtf.balanceOf(address(this)); info.wtf.claimRewards(); _reward += info.wtf.balanceOf(address(this)) - _balanceBefore; info.lastUpdated = _now; _disburse(_reward); } } function deposit(uint256 _amount) external { depositFor(msg.sender, _amount); } function depositFor(address _user, uint256 _amount) public { require(_amount > 0); update(); uint256 _balanceBefore = info.token.balanceOf(address(this)); info.token.transferFrom(msg.sender, address(this), _amount); uint256 _amountReceived = info.token.balanceOf(address(this)) - _balanceBefore; _deposit(_user, _amountReceived); } function tokenCallback(address _from, uint256 _tokens, bytes calldata) external returns (bool) { require(_isWTF() && msg.sender == tokenAddress()); require(_tokens > 0); update(); _deposit(_from, _tokens); return true; } function disburse(uint256 _amount) public { require(_amount > 0); update(); uint256 _balanceBefore = info.wtf.balanceOf(address(this)); info.wtf.transferFrom(msg.sender, address(this), _amount); uint256 _amountReceived = info.wtf.balanceOf(address(this)) - _balanceBefore; _processFee(_amountReceived); } function withdrawAll() public { uint256 _deposited = depositedOf(msg.sender); if (_deposited > 0) { withdraw(_deposited); } } function withdraw(uint256 _amount) public { require(_amount > 0 && _amount <= depositedOf(msg.sender)); update(); info.totalDeposited -= _amount; info.users[msg.sender].deposited -= _amount; info.users[msg.sender].scaledPayout -= int256(_amount * info.scaledRewardsPerToken); uint256 _fee = _calculateFee(_amount); info.token.transfer(msg.sender, _amount - _fee); _processFee(_fee); emit Withdraw(msg.sender, _amount, _fee); } function claim() public { update(); uint256 _rewards = rewardsOf(msg.sender); if (_rewards > 0) { info.users[msg.sender].scaledPayout += int256(_rewards * FLOAT_SCALAR); info.wtf.transfer(msg.sender, _rewards); emit Claim(msg.sender, _rewards); } } function reinvest() public { require(_isWTF()); update(); uint256 _rewards = rewardsOf(msg.sender); if (_rewards > 0) { info.users[msg.sender].scaledPayout += int256(_rewards * FLOAT_SCALAR); _deposit(msg.sender, _rewards); emit Reinvest(msg.sender, _rewards); } } function wtfAddress() public view returns (address) { return address(info.wtf); } function tokenAddress() public view returns (address) { return address(info.token); } function startTime() public view returns (uint256) { return info.startTime; } function totalDeposited() public view returns (uint256) { return info.totalDeposited; } function depositedOf(address _user) public view returns (uint256) { return info.users[_user].deposited; } function rewardsOf(address _user) public view returns (uint256) { return uint256(int256(info.scaledRewardsPerToken * depositedOf(_user)) - info.users[_user].scaledPayout) / FLOAT_SCALAR; } function currentRatePerDay() public view returns (uint256) { if (block.timestamp < startTime()) { return info.totalRewards.mul(_delta(_getX(startTime()), _getX(startTime() + 24 hours))); } else { return info.totalRewards.mul(_delta(_getX(block.timestamp), _getX(block.timestamp + 24 hours))); } } function totalDistributed() public view returns (uint256) { return info.totalRewards.mul(_sum(_getX(block.timestamp))); } function allInfoFor(address _user) external view returns (uint256 startingTime, uint256 totalRewardsDistributed, uint256 rewardsRatePerDay, uint256 currentFeePercent, uint256 totalTokensDeposited, uint256 virtualRewards, uint256 userWTF, uint256 userBalance, uint256 userAllowance, uint256 userDeposited, uint256 userRewards) { startingTime = startTime(); totalRewardsDistributed = totalDistributed(); rewardsRatePerDay = currentRatePerDay(); currentFeePercent = _calculateFee(1e20); totalTokensDeposited = totalDeposited(); virtualRewards = block.timestamp > info.lastUpdated ? info.totalRewards.mul(_delta(_getX(info.lastUpdated), _getX(block.timestamp))) : 0; userWTF = info.wtf.balanceOf(_user); userBalance = info.token.balanceOf(_user); userAllowance = info.token.allowance(_user, address(this)); userDeposited = depositedOf(_user); userRewards = rewardsOf(_user); } function _deposit(address _user, uint256 _amount) internal { uint256 _fee = _calculateFee(_amount); uint256 _deposited = _amount - _fee; info.totalDeposited += _deposited; info.users[_user].deposited += _deposited; info.users[_user].scaledPayout += int256(_deposited * info.scaledRewardsPerToken); _processFee(_fee); emit Deposit(_user, _amount, _fee); } function _processFee(uint256 _fee) internal { if (_fee > 0) { if (block.timestamp < startTime() || totalDeposited() == 0) { info.pendingFee += _fee; } else { _disburse(_fee); } } } function _disburse(uint256 _amount) internal { info.scaledRewardsPerToken += _amount * FLOAT_SCALAR / totalDeposited(); emit Reward(_amount); } function _isWTF() internal view returns (bool) { return wtfAddress() == tokenAddress(); } function _calculateFee(uint256 _amount) internal view returns (uint256) { return _isWTF() ? (_amount * PERCENT_FEE / 100).mul(1e18 - _sum(_getX(block.timestamp))) : 0; } function _getX(uint256 t) internal view returns (uint256) { uint256 _start = startTime(); if (t < _start) { return 0; } else { return ((t - _start) * 1e18).div(X_TICK * 1e18); } } function _sum(uint256 x) internal pure returns (uint256) { uint256 _e2x = x.exp2(); return (_e2x - 1e18).div(_e2x); } function _delta(uint256 x1, uint256 x2) internal pure returns (uint256) { require(x2 >= x1); return _sum(x2) - _sum(x1); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.11; interface ERC20 { function allowance(address, address) external view returns (uint256); function balanceOf(address) external view returns (uint256); function transfer(address, uint256) external returns (bool); function transferFrom(address, address, uint256) external returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.11; import "./WTFNFT.sol"; interface PriceOracle { function getPrice() external view returns (uint256); } contract Metadata { string public name = "fees.wtf NFT"; string public symbol = "fees.wtf"; string constant private TABLE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; WTFNFT public nft; PriceOracle public oracle; constructor(WTFNFT _nft) { nft = _nft; oracle = PriceOracle(0xe89b5B2770Aa1a6BcfAc6F3517510aB8e9146651); } function setPriceOracle(PriceOracle _oracle) external { require(msg.sender == nft.owner()); oracle = _oracle; } function tokenURI(uint256 _tokenId) external view returns (string memory) { ( , , address _user, uint256[7] memory _info) = nft.getToken(_tokenId); return rawTokenURI(_user, _info[0], _info[1], _info[2], _info[3], _info[4], _info[5], _info[6], oracle.getPrice()); } function rawTokenURI(address _user, uint256 _totalFees, uint256 _failFees, uint256 _totalGas, uint256 _avgGwei, uint256 _totalDonated, uint256 _totalTxs, uint256 _failTxs, uint256 _price) public pure returns (string memory) { string memory _json = string(abi.encodePacked('{"name":"', _trimAddress(_user, 6), '","description":"[fees.wtf](https://fees.wtf) snapshot at block 13916450 for [', _address2str(_user), '](https://etherscan.io/address/', _address2str(_user), ')",')); _json = string(abi.encodePacked(_json, '"image":"data:image/svg+xml;base64,', _encode(bytes(getRawSVG(_totalFees, _failFees, _totalGas, _avgGwei, _totalDonated, _totalTxs, _failTxs, _price))), '","attributes":[')); if (_totalFees > 0) { _json = string(abi.encodePacked(_json, '{"trait_type":"Total Fees","value":', _uint2str(_totalFees, 18, 5, false, true), '}')); _json = string(abi.encodePacked(_json, ',{"trait_type":"Fail Fees","value":', _uint2str(_failFees, 18, 5, false, true), '}')); _json = string(abi.encodePacked(_json, ',{"trait_type":"Total Gas","value":', _uint2str(_totalGas, 0, 0, false, false), '}')); _json = string(abi.encodePacked(_json, ',{"trait_type":"Average Gwei","value":', _uint2str(_avgGwei, 9, 5, false, true), '}')); _json = string(abi.encodePacked(_json, ',{"trait_type":"Total Transactions","value":', _uint2str(_totalTxs, 0, 0, false, false), '}')); _json = string(abi.encodePacked(_json, ',{"trait_type":"Failed Transactions","value":', _uint2str(_failTxs, 0, 0, false, false), '}')); _json = string(abi.encodePacked(_json, ',{"display_type":"number","trait_type":"Spender Level","value":', _uint2str(_logn(_totalFees / 1e13, 2), 0, 0, false, false), '}')); _json = string(abi.encodePacked(_json, ',{"display_type":"number","trait_type":"Oof Level","value":', _uint2str(_logn(_failFees / 1e13, 2), 0, 0, false, false), '}')); } if (_totalDonated > 0) { _json = string(abi.encodePacked(_json, _totalFees > 0 ? ',' : '', '{"display_type":"number","trait_type":"Donator Level","value":', _uint2str(_logn(_totalDonated / 1e14, 10) + 1, 0, 0, false, false), '}')); } _json = string(abi.encodePacked(_json, ']}')); return string(abi.encodePacked("data:application/json;base64,", _encode(bytes(_json)))); } function getSVG(uint256 _tokenId) public view returns (string memory) { uint256[7] memory _info = nft.getTokenCompressedInfo(_tokenId); return getRawSVG(_info[0], _info[1], _info[2], _info[3], _info[4], _info[5], _info[6], oracle.getPrice()); } function getRawSVG(uint256 _totalFees, uint256 _failFees, uint256 _totalGas, uint256 _avgGwei, uint256 _totalDonated, uint256 _totalTxs, uint256 _failTxs, uint256 _price) public pure returns (string memory svg) { svg = string(abi.encodePacked("<svg xmlns='http://www.w3.org/2000/svg' version='1.1' preserveAspectRatio='xMidYMid meet' viewBox='0 0 512 512' width='100%' height='100%'>")); svg = string(abi.encodePacked(svg, "<defs><style type='text/css'>text{text-anchor:middle;alignment-baseline:central;}tspan>tspan{fill:#03a9f4;font-weight:700;}</style></defs>")); svg = string(abi.encodePacked(svg, "<rect width='100%' height='100%' fill='#222222' />")); svg = string(abi.encodePacked(svg, "<text x='0' y='256' transform='translate(256)' fill='#f0f8ff' font-family='Arial,sans-serif' font-weight='600' font-size='30'>")); if (_totalFees > 0) { svg = string(abi.encodePacked(svg, unicode"<tspan x='0' dy='-183'>You spent <tspan>Ξ", _uint2str(_totalFees, 18, 5, true, false), "</tspan> on gas</tspan>")); svg = string(abi.encodePacked(svg, "<tspan x='0' dy='35'>before block 13916450.</tspan>")); svg = string(abi.encodePacked(svg, "<tspan x='0' dy='35'>Right now, that's</tspan>")); svg = string(abi.encodePacked(svg, "<tspan x='0' dy='35'><tspan>$", _uint2str(_totalFees * _price / 1e18, 18, 2, true, true), "</tspan>.</tspan>")); svg = string(abi.encodePacked(svg, "<tspan x='0' dy='70'>You used <tspan>", _uint2str(_totalGas, 0, 0, true, false), "</tspan></tspan>")); svg = string(abi.encodePacked(svg, "<tspan x='0' dy='35'>gas to send <tspan>", _uint2str(_totalTxs, 0, 0, true, false), "</tspan></tspan>")); svg = string(abi.encodePacked(svg, "<tspan x='0' dy='35'>transaction", _totalTxs == 1 ? "" : "s", ", with an average</tspan>")); svg = string(abi.encodePacked(svg, "<tspan x='0' dy='35'>price of <tspan>", _uint2str(_avgGwei, 9, 3, true, false), "</tspan> Gwei.</tspan>")); svg = string(abi.encodePacked(svg, "<tspan x='0' dy='70'><tspan>", _uint2str(_failTxs, 0, 0, true, false), "</tspan> of them failed,</tspan>")); svg = string(abi.encodePacked(svg, "<tspan x='0' dy='35'>costing you <tspan>", _failFees == 0 ? "nothing" : string(abi.encodePacked(unicode"Ξ", _uint2str(_failFees, 18, 5, true, false))), "</tspan>.</tspan></text>")); } else { svg = string(abi.encodePacked(svg, "<tspan x='0' dy='8'>Did not qualify.</tspan></text>")); } if (_totalDonated > 0) { for (uint256 i = 0; i <= _logn(_totalDonated / 1e14, 10); i++) { for (uint256 j = 0; j < 4; j++) { string memory _prefix = string(abi.encodePacked("<text x='", j < 2 ? "16" : "496", "' y='", j % 2 == 0 ? "18" : "498", "' font-size='10' transform='translate(")); svg = string(abi.encodePacked(svg, _prefix, j < 2 ? "" : "-", _uint2str(16 * i, 0, 0, false, false), ")'>", unicode"❤️</text>")); if (i > 0) { svg = string(abi.encodePacked(svg, _prefix, "0,", j % 2 == 0 ? "" : "-", _uint2str(16 * i, 0, 0, false, false), ")'>", unicode"❤️</text>")); } } } } svg = string(abi.encodePacked(svg, "<text x='0' y='500' transform='translate(256)' fill='#f0f8ff' font-family='Arial,sans-serif' font-weight='600' font-size='10'><tspan>fees<tspan>.wtf</tspan></tspan></text></svg>")); } function _logn(uint256 _num, uint256 _n) internal pure returns (uint256) { require(_n > 0); uint256 _count = 0; while (_num > _n - 1) { _num /= _n; _count++; } return _count; } function _address2str(address _address) internal pure returns (string memory str) { str = "0x"; for (uint256 i; i < 40; i++) { uint256 _hex = (uint160(_address) >> (4 * (39 - i))) % 16; bytes memory _char = new bytes(1); _char[0] = bytes1(uint8(_hex) + (_hex > 9 ? 87 : 48)); str = string(abi.encodePacked(str, string(_char))); } } function _trimAddress(address _address, uint256 _padding) internal pure returns (string memory str) { require(_padding < 20); str = ""; bytes memory _strAddress = bytes(_address2str(_address)); uint256 _length = 2 * _padding + 2; for (uint256 i = 0; i < 2 * _padding + 2; i++) { bytes memory _char = new bytes(1); _char[0] = _strAddress[i < _padding + 2 ? i : 42 + i - _length]; str = string(abi.encodePacked(str, string(_char))); if (i == _padding + 1) { str = string(abi.encodePacked(str, unicode"…")); } } } function _uint2str(uint256 _value, uint256 _scale, uint256 _maxDecimals, bool _commas, bool _full) internal pure returns (string memory str) { uint256 _d = _scale > _maxDecimals ? _maxDecimals : _scale; uint256 _n = _value / 10**(_scale > _d ? _scale - _d : 0); if (_n == 0) { return "0"; } uint256 _digits = 1; uint256 _tmp = _n; while (_tmp > 9) { _tmp /= 10; _digits++; } _tmp = _digits > _d ? _digits : _d + 1; uint256 _offset = (!_full && _tmp > _d + 1 ? _tmp - _d - 1 > _d ? _d : _tmp - _d - 1 : 0); for (uint256 i = 0; i < _tmp - _offset; i++) { uint256 _dec = i < _tmp - _digits ? 0 : (_n / (10**(_tmp - i - 1))) % 10; bytes memory _char = new bytes(1); _char[0] = bytes1(uint8(_dec) + 48); str = string(abi.encodePacked(str, string(_char))); if (i < _tmp - _d - 1) { if (_commas && (i + 1) % 3 == (_tmp - _d) % 3) { str = string(abi.encodePacked(str, ",")); } } else { if (!_full && (_n / 10**_offset) % 10**(_tmp - _offset - i - 1) == 0) { break; } else if (i == _tmp - _d - 1) { str = string(abi.encodePacked(str, ".")); } } } } function _encode(bytes memory _data) internal pure returns (string memory result) { if (_data.length == 0) return ''; string memory _table = TABLE; uint256 _encodedLen = 4 * ((_data.length + 2) / 3); result = new string(_encodedLen + 32); assembly { mstore(result, _encodedLen) let tablePtr := add(_table, 1) let dataPtr := _data let endPtr := add(dataPtr, mload(_data)) let resultPtr := add(result, 32) for {} lt(dataPtr, endPtr) {} { dataPtr := add(dataPtr, 3) let input := mload(dataPtr) mstore(resultPtr, shl(248, mload(add(tablePtr, and(shr(18, input), 0x3F))))) resultPtr := add(resultPtr, 1) mstore(resultPtr, shl(248, mload(add(tablePtr, and(shr(12, input), 0x3F))))) resultPtr := add(resultPtr, 1) mstore(resultPtr, shl(248, mload(add(tablePtr, and(shr( 6, input), 0x3F))))) resultPtr := add(resultPtr, 1) mstore(resultPtr, shl(248, mload(add(tablePtr, and( input, 0x3F))))) resultPtr := add(resultPtr, 1) } switch mod(mload(_data), 3) case 1 { mstore(sub(resultPtr, 2), shl(240, 0x3d3d)) } case 2 { mstore(sub(resultPtr, 1), shl(248, 0x3d)) } } return result; } }
// SPDX-License-Identifier: Unlicense pragma solidity >=0.8.4; /// @notice Emitted when the result overflows uint256. error PRBMath__MulDivFixedPointOverflow(uint256 prod1); /// @notice Emitted when the result overflows uint256. error PRBMath__MulDivOverflow(uint256 prod1, uint256 denominator); /// @notice Emitted when one of the inputs is type(int256).min. error PRBMath__MulDivSignedInputTooSmall(); /// @notice Emitted when the intermediary absolute result overflows int256. error PRBMath__MulDivSignedOverflow(uint256 rAbs); /// @notice Emitted when the input is MIN_SD59x18. error PRBMathSD59x18__AbsInputTooSmall(); /// @notice Emitted when ceiling a number overflows SD59x18. error PRBMathSD59x18__CeilOverflow(int256 x); /// @notice Emitted when one of the inputs is MIN_SD59x18. error PRBMathSD59x18__DivInputTooSmall(); /// @notice Emitted when one of the intermediary unsigned results overflows SD59x18. error PRBMathSD59x18__DivOverflow(uint256 rAbs); /// @notice Emitted when the input is greater than 133.084258667509499441. error PRBMathSD59x18__ExpInputTooBig(int256 x); /// @notice Emitted when the input is greater than 192. error PRBMathSD59x18__Exp2InputTooBig(int256 x); /// @notice Emitted when flooring a number underflows SD59x18. error PRBMathSD59x18__FloorUnderflow(int256 x); /// @notice Emitted when converting a basic integer to the fixed-point format overflows SD59x18. error PRBMathSD59x18__FromIntOverflow(int256 x); /// @notice Emitted when converting a basic integer to the fixed-point format underflows SD59x18. error PRBMathSD59x18__FromIntUnderflow(int256 x); /// @notice Emitted when the product of the inputs is negative. error PRBMathSD59x18__GmNegativeProduct(int256 x, int256 y); /// @notice Emitted when multiplying the inputs overflows SD59x18. error PRBMathSD59x18__GmOverflow(int256 x, int256 y); /// @notice Emitted when the input is less than or equal to zero. error PRBMathSD59x18__LogInputTooSmall(int256 x); /// @notice Emitted when one of the inputs is MIN_SD59x18. error PRBMathSD59x18__MulInputTooSmall(); /// @notice Emitted when the intermediary absolute result overflows SD59x18. error PRBMathSD59x18__MulOverflow(uint256 rAbs); /// @notice Emitted when the intermediary absolute result overflows SD59x18. error PRBMathSD59x18__PowuOverflow(uint256 rAbs); /// @notice Emitted when the input is negative. error PRBMathSD59x18__SqrtNegativeInput(int256 x); /// @notice Emitted when the calculating the square root overflows SD59x18. error PRBMathSD59x18__SqrtOverflow(int256 x); /// @notice Emitted when addition overflows UD60x18. error PRBMathUD60x18__AddOverflow(uint256 x, uint256 y); /// @notice Emitted when ceiling a number overflows UD60x18. error PRBMathUD60x18__CeilOverflow(uint256 x); /// @notice Emitted when the input is greater than 133.084258667509499441. error PRBMathUD60x18__ExpInputTooBig(uint256 x); /// @notice Emitted when the input is greater than 192. error PRBMathUD60x18__Exp2InputTooBig(uint256 x); /// @notice Emitted when converting a basic integer to the fixed-point format format overflows UD60x18. error PRBMathUD60x18__FromUintOverflow(uint256 x); /// @notice Emitted when multiplying the inputs overflows UD60x18. error PRBMathUD60x18__GmOverflow(uint256 x, uint256 y); /// @notice Emitted when the input is less than 1. error PRBMathUD60x18__LogInputTooSmall(uint256 x); /// @notice Emitted when the calculating the square root overflows UD60x18. error PRBMathUD60x18__SqrtOverflow(uint256 x); /// @notice Emitted when subtraction underflows UD60x18. error PRBMathUD60x18__SubUnderflow(uint256 x, uint256 y); /// @dev Common mathematical functions used in both PRBMathSD59x18 and PRBMathUD60x18. Note that this shared library /// does not always assume the signed 59.18-decimal fixed-point or the unsigned 60.18-decimal fixed-point /// representation. When it does not, it is explicitly mentioned in the NatSpec documentation. library PRBMath { /// STRUCTS /// struct SD59x18 { int256 value; } struct UD60x18 { uint256 value; } /// STORAGE /// /// @dev How many trailing decimals can be represented. uint256 internal constant SCALE = 1e18; /// @dev Largest power of two divisor of SCALE. uint256 internal constant SCALE_LPOTD = 262144; /// @dev SCALE inverted mod 2^256. uint256 internal constant SCALE_INVERSE = 78156646155174841979727994598816262306175212592076161876661_508869554232690281; /// FUNCTIONS /// /// @notice Calculates the binary exponent of x using the binary fraction method. /// @dev Has to use 192.64-bit fixed-point numbers. /// See https://ethereum.stackexchange.com/a/96594/24693. /// @param x The exponent as an unsigned 192.64-bit fixed-point number. /// @return result The result as an unsigned 60.18-decimal fixed-point number. function exp2(uint256 x) internal pure returns (uint256 result) { unchecked { // Start from 0.5 in the 192.64-bit fixed-point format. result = 0x800000000000000000000000000000000000000000000000; // Multiply the result by root(2, 2^-i) when the bit at position i is 1. None of the intermediary results overflows // because the initial result is 2^191 and all magic factors are less than 2^65. if (x & 0x8000000000000000 > 0) { result = (result * 0x16A09E667F3BCC909) >> 64; } if (x & 0x4000000000000000 > 0) { result = (result * 0x1306FE0A31B7152DF) >> 64; } if (x & 0x2000000000000000 > 0) { result = (result * 0x1172B83C7D517ADCE) >> 64; } if (x & 0x1000000000000000 > 0) { result = (result * 0x10B5586CF9890F62A) >> 64; } if (x & 0x800000000000000 > 0) { result = (result * 0x1059B0D31585743AE) >> 64; } if (x & 0x400000000000000 > 0) { result = (result * 0x102C9A3E778060EE7) >> 64; } if (x & 0x200000000000000 > 0) { result = (result * 0x10163DA9FB33356D8) >> 64; } if (x & 0x100000000000000 > 0) { result = (result * 0x100B1AFA5ABCBED61) >> 64; } if (x & 0x80000000000000 > 0) { result = (result * 0x10058C86DA1C09EA2) >> 64; } if (x & 0x40000000000000 > 0) { result = (result * 0x1002C605E2E8CEC50) >> 64; } if (x & 0x20000000000000 > 0) { result = (result * 0x100162F3904051FA1) >> 64; } if (x & 0x10000000000000 > 0) { result = (result * 0x1000B175EFFDC76BA) >> 64; } if (x & 0x8000000000000 > 0) { result = (result * 0x100058BA01FB9F96D) >> 64; } if (x & 0x4000000000000 > 0) { result = (result * 0x10002C5CC37DA9492) >> 64; } if (x & 0x2000000000000 > 0) { result = (result * 0x1000162E525EE0547) >> 64; } if (x & 0x1000000000000 > 0) { result = (result * 0x10000B17255775C04) >> 64; } if (x & 0x800000000000 > 0) { result = (result * 0x1000058B91B5BC9AE) >> 64; } if (x & 0x400000000000 > 0) { result = (result * 0x100002C5C89D5EC6D) >> 64; } if (x & 0x200000000000 > 0) { result = (result * 0x10000162E43F4F831) >> 64; } if (x & 0x100000000000 > 0) { result = (result * 0x100000B1721BCFC9A) >> 64; } if (x & 0x80000000000 > 0) { result = (result * 0x10000058B90CF1E6E) >> 64; } if (x & 0x40000000000 > 0) { result = (result * 0x1000002C5C863B73F) >> 64; } if (x & 0x20000000000 > 0) { result = (result * 0x100000162E430E5A2) >> 64; } if (x & 0x10000000000 > 0) { result = (result * 0x1000000B172183551) >> 64; } if (x & 0x8000000000 > 0) { result = (result * 0x100000058B90C0B49) >> 64; } if (x & 0x4000000000 > 0) { result = (result * 0x10000002C5C8601CC) >> 64; } if (x & 0x2000000000 > 0) { result = (result * 0x1000000162E42FFF0) >> 64; } if (x & 0x1000000000 > 0) { result = (result * 0x10000000B17217FBB) >> 64; } if (x & 0x800000000 > 0) { result = (result * 0x1000000058B90BFCE) >> 64; } if (x & 0x400000000 > 0) { result = (result * 0x100000002C5C85FE3) >> 64; } if (x & 0x200000000 > 0) { result = (result * 0x10000000162E42FF1) >> 64; } if (x & 0x100000000 > 0) { result = (result * 0x100000000B17217F8) >> 64; } if (x & 0x80000000 > 0) { result = (result * 0x10000000058B90BFC) >> 64; } if (x & 0x40000000 > 0) { result = (result * 0x1000000002C5C85FE) >> 64; } if (x & 0x20000000 > 0) { result = (result * 0x100000000162E42FF) >> 64; } if (x & 0x10000000 > 0) { result = (result * 0x1000000000B17217F) >> 64; } if (x & 0x8000000 > 0) { result = (result * 0x100000000058B90C0) >> 64; } if (x & 0x4000000 > 0) { result = (result * 0x10000000002C5C860) >> 64; } if (x & 0x2000000 > 0) { result = (result * 0x1000000000162E430) >> 64; } if (x & 0x1000000 > 0) { result = (result * 0x10000000000B17218) >> 64; } if (x & 0x800000 > 0) { result = (result * 0x1000000000058B90C) >> 64; } if (x & 0x400000 > 0) { result = (result * 0x100000000002C5C86) >> 64; } if (x & 0x200000 > 0) { result = (result * 0x10000000000162E43) >> 64; } if (x & 0x100000 > 0) { result = (result * 0x100000000000B1721) >> 64; } if (x & 0x80000 > 0) { result = (result * 0x10000000000058B91) >> 64; } if (x & 0x40000 > 0) { result = (result * 0x1000000000002C5C8) >> 64; } if (x & 0x20000 > 0) { result = (result * 0x100000000000162E4) >> 64; } if (x & 0x10000 > 0) { result = (result * 0x1000000000000B172) >> 64; } if (x & 0x8000 > 0) { result = (result * 0x100000000000058B9) >> 64; } if (x & 0x4000 > 0) { result = (result * 0x10000000000002C5D) >> 64; } if (x & 0x2000 > 0) { result = (result * 0x1000000000000162E) >> 64; } if (x & 0x1000 > 0) { result = (result * 0x10000000000000B17) >> 64; } if (x & 0x800 > 0) { result = (result * 0x1000000000000058C) >> 64; } if (x & 0x400 > 0) { result = (result * 0x100000000000002C6) >> 64; } if (x & 0x200 > 0) { result = (result * 0x10000000000000163) >> 64; } if (x & 0x100 > 0) { result = (result * 0x100000000000000B1) >> 64; } if (x & 0x80 > 0) { result = (result * 0x10000000000000059) >> 64; } if (x & 0x40 > 0) { result = (result * 0x1000000000000002C) >> 64; } if (x & 0x20 > 0) { result = (result * 0x10000000000000016) >> 64; } if (x & 0x10 > 0) { result = (result * 0x1000000000000000B) >> 64; } if (x & 0x8 > 0) { result = (result * 0x10000000000000006) >> 64; } if (x & 0x4 > 0) { result = (result * 0x10000000000000003) >> 64; } if (x & 0x2 > 0) { result = (result * 0x10000000000000001) >> 64; } if (x & 0x1 > 0) { result = (result * 0x10000000000000001) >> 64; } // We're doing two things at the same time: // // 1. Multiply the result by 2^n + 1, where "2^n" is the integer part and the one is added to account for // the fact that we initially set the result to 0.5. This is accomplished by subtracting from 191 // rather than 192. // 2. Convert the result to the unsigned 60.18-decimal fixed-point format. // // This works because 2^(191-ip) = 2^ip / 2^191, where "ip" is the integer part "2^n". result *= SCALE; result >>= (191 - (x >> 64)); } } /// @notice Finds the zero-based index of the first one in the binary representation of x. /// @dev See the note on msb in the "Find First Set" Wikipedia article https://en.wikipedia.org/wiki/Find_first_set /// @param x The uint256 number for which to find the index of the most significant bit. /// @return msb The index of the most significant bit as an uint256. function mostSignificantBit(uint256 x) internal pure returns (uint256 msb) { if (x >= 2**128) { x >>= 128; msb += 128; } if (x >= 2**64) { x >>= 64; msb += 64; } if (x >= 2**32) { x >>= 32; msb += 32; } if (x >= 2**16) { x >>= 16; msb += 16; } if (x >= 2**8) { x >>= 8; msb += 8; } if (x >= 2**4) { x >>= 4; msb += 4; } if (x >= 2**2) { x >>= 2; msb += 2; } if (x >= 2**1) { // No need to shift x any more. msb += 1; } } /// @notice Calculates floor(x*y÷denominator) with full precision. /// /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv. /// /// Requirements: /// - The denominator cannot be zero. /// - The result must fit within uint256. /// /// Caveats: /// - This function does not work with fixed-point numbers. /// /// @param x The multiplicand as an uint256. /// @param y The multiplier as an uint256. /// @param denominator The divisor as an uint256. /// @return result The result as an uint256. function mulDiv( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 result) { // 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) { unchecked { result = prod0 / denominator; } return result; } // Make sure the result is less than 2^256. Also prevents denominator == 0. if (prod1 >= denominator) { revert PRBMath__MulDivOverflow(prod1, denominator); } /////////////////////////////////////////////// // 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. unchecked { // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 lpotdod = denominator & (~denominator + 1); assembly { // Divide denominator by lpotdod. denominator := div(denominator, lpotdod) // Divide [prod1 prod0] by lpotdod. prod0 := div(prod0, lpotdod) // Flip lpotdod such that it is 2^256 / lpotdod. If lpotdod is zero, then it becomes one. lpotdod := add(div(sub(0, lpotdod), lpotdod), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * lpotdod; // 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 floor(x*y÷1e18) with full precision. /// /// @dev Variant of "mulDiv" with constant folding, i.e. in which the denominator is always 1e18. Before returning the /// final result, we add 1 if (x * y) % SCALE >= HALF_SCALE. Without this, 6.6e-19 would be truncated to 0 instead of /// being rounded to 1e-18. See "Listing 6" and text above it at https://accu.org/index.php/journals/1717. /// /// Requirements: /// - The result must fit within uint256. /// /// Caveats: /// - The body is purposely left uncommented; see the NatSpec comments in "PRBMath.mulDiv" to understand how this works. /// - It is assumed that the result can never be type(uint256).max when x and y solve the following two equations: /// 1. x * y = type(uint256).max * SCALE /// 2. (x * y) % SCALE >= SCALE / 2 /// /// @param x The multiplicand as an unsigned 60.18-decimal fixed-point number. /// @param y The multiplier as an unsigned 60.18-decimal fixed-point number. /// @return result The result as an unsigned 60.18-decimal fixed-point number. function mulDivFixedPoint(uint256 x, uint256 y) internal pure returns (uint256 result) { uint256 prod0; uint256 prod1; assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } if (prod1 >= SCALE) { revert PRBMath__MulDivFixedPointOverflow(prod1); } uint256 remainder; uint256 roundUpUnit; assembly { remainder := mulmod(x, y, SCALE) roundUpUnit := gt(remainder, 499999999999999999) } if (prod1 == 0) { unchecked { result = (prod0 / SCALE) + roundUpUnit; return result; } } assembly { result := add( mul( or( div(sub(prod0, remainder), SCALE_LPOTD), mul(sub(prod1, gt(remainder, prod0)), add(div(sub(0, SCALE_LPOTD), SCALE_LPOTD), 1)) ), SCALE_INVERSE ), roundUpUnit ) } } /// @notice Calculates floor(x*y÷denominator) with full precision. /// /// @dev An extension of "mulDiv" for signed numbers. Works by computing the signs and the absolute values separately. /// /// Requirements: /// - None of the inputs can be type(int256).min. /// - The result must fit within int256. /// /// @param x The multiplicand as an int256. /// @param y The multiplier as an int256. /// @param denominator The divisor as an int256. /// @return result The result as an int256. function mulDivSigned( int256 x, int256 y, int256 denominator ) internal pure returns (int256 result) { if (x == type(int256).min || y == type(int256).min || denominator == type(int256).min) { revert PRBMath__MulDivSignedInputTooSmall(); } // Get hold of the absolute values of x, y and the denominator. uint256 ax; uint256 ay; uint256 ad; unchecked { ax = x < 0 ? uint256(-x) : uint256(x); ay = y < 0 ? uint256(-y) : uint256(y); ad = denominator < 0 ? uint256(-denominator) : uint256(denominator); } // Compute the absolute value of (x*y)÷denominator. The result must fit within int256. uint256 rAbs = mulDiv(ax, ay, ad); if (rAbs > uint256(type(int256).max)) { revert PRBMath__MulDivSignedOverflow(rAbs); } // Get the signs of x, y and the denominator. uint256 sx; uint256 sy; uint256 sd; assembly { sx := sgt(x, sub(0, 1)) sy := sgt(y, sub(0, 1)) sd := sgt(denominator, sub(0, 1)) } // XOR over sx, sy and sd. This is checking whether there are one or three negative signs in the inputs. // If yes, the result should be negative. result = sx ^ sy ^ sd == 0 ? -int256(rAbs) : int256(rAbs); } /// @notice Calculates the square root of x, rounding down. /// @dev Uses the Babylonian method https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method. /// /// Caveats: /// - This function does not work with fixed-point numbers. /// /// @param x The uint256 number for which to calculate the square root. /// @return result The result as an uint256. function sqrt(uint256 x) internal pure returns (uint256 result) { if (x == 0) { return 0; } // Set the initial guess to the least power of two that is greater than or equal to sqrt(x). uint256 xAux = uint256(x); result = 1; if (xAux >= 0x100000000000000000000000000000000) { xAux >>= 128; result <<= 64; } if (xAux >= 0x10000000000000000) { xAux >>= 64; result <<= 32; } if (xAux >= 0x100000000) { xAux >>= 32; result <<= 16; } if (xAux >= 0x10000) { xAux >>= 16; result <<= 8; } if (xAux >= 0x100) { xAux >>= 8; result <<= 4; } if (xAux >= 0x10) { xAux >>= 4; result <<= 2; } if (xAux >= 0x8) { result <<= 1; } // The operations can never overflow because the result is max 2^127 when it enters this block. unchecked { result = (result + x / result) >> 1; result = (result + x / result) >> 1; result = (result + x / result) >> 1; result = (result + x / result) >> 1; result = (result + x / result) >> 1; result = (result + x / result) >> 1; result = (result + x / result) >> 1; // Seven iterations should be enough uint256 roundedDownResult = x / result; return result >= roundedDownResult ? roundedDownResult : result; } } }
// SPDX-License-Identifier: Unlicense pragma solidity >=0.8.4; import "./PRBMath.sol"; /// @title PRBMathUD60x18 /// @author Paul Razvan Berg /// @notice Smart contract library for advanced fixed-point math that works with uint256 numbers considered to have 18 /// trailing decimals. We call this number representation unsigned 60.18-decimal fixed-point, since there can be up to 60 /// digits in the integer part and up to 18 decimals in the fractional part. The numbers are bound by the minimum and the /// maximum values permitted by the Solidity type uint256. library PRBMathUD60x18 { /// @dev Half the SCALE number. uint256 internal constant HALF_SCALE = 5e17; /// @dev log2(e) as an unsigned 60.18-decimal fixed-point number. uint256 internal constant LOG2_E = 1_442695040888963407; /// @dev The maximum value an unsigned 60.18-decimal fixed-point number can have. uint256 internal constant MAX_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_584007913129639935; /// @dev The maximum whole value an unsigned 60.18-decimal fixed-point number can have. uint256 internal constant MAX_WHOLE_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_000000000000000000; /// @dev How many trailing decimals can be represented. uint256 internal constant SCALE = 1e18; /// @notice Calculates the arithmetic average of x and y, rounding down. /// @param x The first operand as an unsigned 60.18-decimal fixed-point number. /// @param y The second operand as an unsigned 60.18-decimal fixed-point number. /// @return result The arithmetic average as an unsigned 60.18-decimal fixed-point number. function avg(uint256 x, uint256 y) internal pure returns (uint256 result) { // The operations can never overflow. unchecked { // The last operand checks if both x and y are odd and if that is the case, we add 1 to the result. We need // to do this because if both numbers are odd, the 0.5 remainder gets truncated twice. result = (x >> 1) + (y >> 1) + (x & y & 1); } } /// @notice Yields the least unsigned 60.18 decimal fixed-point number greater than or equal to x. /// /// @dev Optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional counterparts. /// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions. /// /// Requirements: /// - x must be less than or equal to MAX_WHOLE_UD60x18. /// /// @param x The unsigned 60.18-decimal fixed-point number to ceil. /// @param result The least integer greater than or equal to x, as an unsigned 60.18-decimal fixed-point number. function ceil(uint256 x) internal pure returns (uint256 result) { if (x > MAX_WHOLE_UD60x18) { revert PRBMathUD60x18__CeilOverflow(x); } assembly { // Equivalent to "x % SCALE" but faster. let remainder := mod(x, SCALE) // Equivalent to "SCALE - remainder" but faster. let delta := sub(SCALE, remainder) // Equivalent to "x + delta * (remainder > 0 ? 1 : 0)" but faster. result := add(x, mul(delta, gt(remainder, 0))) } } /// @notice Divides two unsigned 60.18-decimal fixed-point numbers, returning a new unsigned 60.18-decimal fixed-point number. /// /// @dev Uses mulDiv to enable overflow-safe multiplication and division. /// /// Requirements: /// - The denominator cannot be zero. /// /// @param x The numerator as an unsigned 60.18-decimal fixed-point number. /// @param y The denominator as an unsigned 60.18-decimal fixed-point number. /// @param result The quotient as an unsigned 60.18-decimal fixed-point number. function div(uint256 x, uint256 y) internal pure returns (uint256 result) { result = PRBMath.mulDiv(x, SCALE, y); } /// @notice Returns Euler's number as an unsigned 60.18-decimal fixed-point number. /// @dev See https://en.wikipedia.org/wiki/E_(mathematical_constant). function e() internal pure returns (uint256 result) { result = 2_718281828459045235; } /// @notice Calculates the natural exponent of x. /// /// @dev Based on the insight that e^x = 2^(x * log2(e)). /// /// Requirements: /// - All from "log2". /// - x must be less than 133.084258667509499441. /// /// @param x The exponent as an unsigned 60.18-decimal fixed-point number. /// @return result The result as an unsigned 60.18-decimal fixed-point number. function exp(uint256 x) internal pure returns (uint256 result) { // Without this check, the value passed to "exp2" would be greater than 192. if (x >= 133_084258667509499441) { revert PRBMathUD60x18__ExpInputTooBig(x); } // Do the fixed-point multiplication inline to save gas. unchecked { uint256 doubleScaleProduct = x * LOG2_E; result = exp2((doubleScaleProduct + HALF_SCALE) / SCALE); } } /// @notice Calculates the binary exponent of x using the binary fraction method. /// /// @dev See https://ethereum.stackexchange.com/q/79903/24693. /// /// Requirements: /// - x must be 192 or less. /// - The result must fit within MAX_UD60x18. /// /// @param x The exponent as an unsigned 60.18-decimal fixed-point number. /// @return result The result as an unsigned 60.18-decimal fixed-point number. function exp2(uint256 x) internal pure returns (uint256 result) { // 2^192 doesn't fit within the 192.64-bit format used internally in this function. if (x >= 192e18) { revert PRBMathUD60x18__Exp2InputTooBig(x); } unchecked { // Convert x to the 192.64-bit fixed-point format. uint256 x192x64 = (x << 64) / SCALE; // Pass x to the PRBMath.exp2 function, which uses the 192.64-bit fixed-point number representation. result = PRBMath.exp2(x192x64); } } /// @notice Yields the greatest unsigned 60.18 decimal fixed-point number less than or equal to x. /// @dev Optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional counterparts. /// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions. /// @param x The unsigned 60.18-decimal fixed-point number to floor. /// @param result The greatest integer less than or equal to x, as an unsigned 60.18-decimal fixed-point number. function floor(uint256 x) internal pure returns (uint256 result) { assembly { // Equivalent to "x % SCALE" but faster. let remainder := mod(x, SCALE) // Equivalent to "x - remainder * (remainder > 0 ? 1 : 0)" but faster. result := sub(x, mul(remainder, gt(remainder, 0))) } } /// @notice Yields the excess beyond the floor of x. /// @dev Based on the odd function definition https://en.wikipedia.org/wiki/Fractional_part. /// @param x The unsigned 60.18-decimal fixed-point number to get the fractional part of. /// @param result The fractional part of x as an unsigned 60.18-decimal fixed-point number. function frac(uint256 x) internal pure returns (uint256 result) { assembly { result := mod(x, SCALE) } } /// @notice Converts a number from basic integer form to unsigned 60.18-decimal fixed-point representation. /// /// @dev Requirements: /// - x must be less than or equal to MAX_UD60x18 divided by SCALE. /// /// @param x The basic integer to convert. /// @param result The same number in unsigned 60.18-decimal fixed-point representation. function fromUint(uint256 x) internal pure returns (uint256 result) { unchecked { if (x > MAX_UD60x18 / SCALE) { revert PRBMathUD60x18__FromUintOverflow(x); } result = x * SCALE; } } /// @notice Calculates geometric mean of x and y, i.e. sqrt(x * y), rounding down. /// /// @dev Requirements: /// - x * y must fit within MAX_UD60x18, lest it overflows. /// /// @param x The first operand as an unsigned 60.18-decimal fixed-point number. /// @param y The second operand as an unsigned 60.18-decimal fixed-point number. /// @return result The result as an unsigned 60.18-decimal fixed-point number. function gm(uint256 x, uint256 y) internal pure returns (uint256 result) { if (x == 0) { return 0; } unchecked { // Checking for overflow this way is faster than letting Solidity do it. uint256 xy = x * y; if (xy / x != y) { revert PRBMathUD60x18__GmOverflow(x, y); } // We don't need to multiply by the SCALE here because the x*y product had already picked up a factor of SCALE // during multiplication. See the comments within the "sqrt" function. result = PRBMath.sqrt(xy); } } /// @notice Calculates 1 / x, rounding toward zero. /// /// @dev Requirements: /// - x cannot be zero. /// /// @param x The unsigned 60.18-decimal fixed-point number for which to calculate the inverse. /// @return result The inverse as an unsigned 60.18-decimal fixed-point number. function inv(uint256 x) internal pure returns (uint256 result) { unchecked { // 1e36 is SCALE * SCALE. result = 1e36 / x; } } /// @notice Calculates the natural logarithm of x. /// /// @dev Based on the insight that ln(x) = log2(x) / log2(e). /// /// Requirements: /// - All from "log2". /// /// Caveats: /// - All from "log2". /// - This doesn't return exactly 1 for 2.718281828459045235, for that we would need more fine-grained precision. /// /// @param x The unsigned 60.18-decimal fixed-point number for which to calculate the natural logarithm. /// @return result The natural logarithm as an unsigned 60.18-decimal fixed-point number. function ln(uint256 x) internal pure returns (uint256 result) { // Do the fixed-point multiplication inline to save gas. This is overflow-safe because the maximum value that log2(x) // can return is 196205294292027477728. unchecked { result = (log2(x) * SCALE) / LOG2_E; } } /// @notice Calculates the common logarithm of x. /// /// @dev First checks if x is an exact power of ten and it stops if yes. If it's not, calculates the common /// logarithm based on the insight that log10(x) = log2(x) / log2(10). /// /// Requirements: /// - All from "log2". /// /// Caveats: /// - All from "log2". /// /// @param x The unsigned 60.18-decimal fixed-point number for which to calculate the common logarithm. /// @return result The common logarithm as an unsigned 60.18-decimal fixed-point number. function log10(uint256 x) internal pure returns (uint256 result) { if (x < SCALE) { revert PRBMathUD60x18__LogInputTooSmall(x); } // Note that the "mul" in this block is the assembly multiplication operation, not the "mul" function defined // in this contract. // prettier-ignore assembly { switch x case 1 { result := mul(SCALE, sub(0, 18)) } case 10 { result := mul(SCALE, sub(1, 18)) } case 100 { result := mul(SCALE, sub(2, 18)) } case 1000 { result := mul(SCALE, sub(3, 18)) } case 10000 { result := mul(SCALE, sub(4, 18)) } case 100000 { result := mul(SCALE, sub(5, 18)) } case 1000000 { result := mul(SCALE, sub(6, 18)) } case 10000000 { result := mul(SCALE, sub(7, 18)) } case 100000000 { result := mul(SCALE, sub(8, 18)) } case 1000000000 { result := mul(SCALE, sub(9, 18)) } case 10000000000 { result := mul(SCALE, sub(10, 18)) } case 100000000000 { result := mul(SCALE, sub(11, 18)) } case 1000000000000 { result := mul(SCALE, sub(12, 18)) } case 10000000000000 { result := mul(SCALE, sub(13, 18)) } case 100000000000000 { result := mul(SCALE, sub(14, 18)) } case 1000000000000000 { result := mul(SCALE, sub(15, 18)) } case 10000000000000000 { result := mul(SCALE, sub(16, 18)) } case 100000000000000000 { result := mul(SCALE, sub(17, 18)) } case 1000000000000000000 { result := 0 } case 10000000000000000000 { result := SCALE } case 100000000000000000000 { result := mul(SCALE, 2) } case 1000000000000000000000 { result := mul(SCALE, 3) } case 10000000000000000000000 { result := mul(SCALE, 4) } case 100000000000000000000000 { result := mul(SCALE, 5) } case 1000000000000000000000000 { result := mul(SCALE, 6) } case 10000000000000000000000000 { result := mul(SCALE, 7) } case 100000000000000000000000000 { result := mul(SCALE, 8) } case 1000000000000000000000000000 { result := mul(SCALE, 9) } case 10000000000000000000000000000 { result := mul(SCALE, 10) } case 100000000000000000000000000000 { result := mul(SCALE, 11) } case 1000000000000000000000000000000 { result := mul(SCALE, 12) } case 10000000000000000000000000000000 { result := mul(SCALE, 13) } case 100000000000000000000000000000000 { result := mul(SCALE, 14) } case 1000000000000000000000000000000000 { result := mul(SCALE, 15) } case 10000000000000000000000000000000000 { result := mul(SCALE, 16) } case 100000000000000000000000000000000000 { result := mul(SCALE, 17) } case 1000000000000000000000000000000000000 { result := mul(SCALE, 18) } case 10000000000000000000000000000000000000 { result := mul(SCALE, 19) } case 100000000000000000000000000000000000000 { result := mul(SCALE, 20) } case 1000000000000000000000000000000000000000 { result := mul(SCALE, 21) } case 10000000000000000000000000000000000000000 { result := mul(SCALE, 22) } case 100000000000000000000000000000000000000000 { result := mul(SCALE, 23) } case 1000000000000000000000000000000000000000000 { result := mul(SCALE, 24) } case 10000000000000000000000000000000000000000000 { result := mul(SCALE, 25) } case 100000000000000000000000000000000000000000000 { result := mul(SCALE, 26) } case 1000000000000000000000000000000000000000000000 { result := mul(SCALE, 27) } case 10000000000000000000000000000000000000000000000 { result := mul(SCALE, 28) } case 100000000000000000000000000000000000000000000000 { result := mul(SCALE, 29) } case 1000000000000000000000000000000000000000000000000 { result := mul(SCALE, 30) } case 10000000000000000000000000000000000000000000000000 { result := mul(SCALE, 31) } case 100000000000000000000000000000000000000000000000000 { result := mul(SCALE, 32) } case 1000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 33) } case 10000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 34) } case 100000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 35) } case 1000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 36) } case 10000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 37) } case 100000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 38) } case 1000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 39) } case 10000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 40) } case 100000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 41) } case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 42) } case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 43) } case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 44) } case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 45) } case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 46) } case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 47) } case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 48) } case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 49) } case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 50) } case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 51) } case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 52) } case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 53) } case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 54) } case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 55) } case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 56) } case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 57) } case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 58) } case 100000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 59) } default { result := MAX_UD60x18 } } if (result == MAX_UD60x18) { // Do the fixed-point division inline to save gas. The denominator is log2(10). unchecked { result = (log2(x) * SCALE) / 3_321928094887362347; } } } /// @notice Calculates the binary logarithm of x. /// /// @dev Based on the iterative approximation algorithm. /// https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation /// /// Requirements: /// - x must be greater than or equal to SCALE, otherwise the result would be negative. /// /// Caveats: /// - The results are nor perfectly accurate to the last decimal, due to the lossy precision of the iterative approximation. /// /// @param x The unsigned 60.18-decimal fixed-point number for which to calculate the binary logarithm. /// @return result The binary logarithm as an unsigned 60.18-decimal fixed-point number. function log2(uint256 x) internal pure returns (uint256 result) { if (x < SCALE) { revert PRBMathUD60x18__LogInputTooSmall(x); } unchecked { // Calculate the integer part of the logarithm and add it to the result and finally calculate y = x * 2^(-n). uint256 n = PRBMath.mostSignificantBit(x / SCALE); // The integer part of the logarithm as an unsigned 60.18-decimal fixed-point number. The operation can't overflow // because n is maximum 255 and SCALE is 1e18. result = n * SCALE; // This is y = x * 2^(-n). uint256 y = x >> n; // If y = 1, the fractional part is zero. if (y == SCALE) { return result; } // Calculate the fractional part via the iterative approximation. // The "delta >>= 1" part is equivalent to "delta /= 2", but shifting bits is faster. for (uint256 delta = HALF_SCALE; delta > 0; delta >>= 1) { y = (y * y) / SCALE; // Is y^2 > 2 and so in the range [2,4)? if (y >= 2 * SCALE) { // Add the 2^(-m) factor to the logarithm. result += delta; // Corresponds to z/2 on Wikipedia. y >>= 1; } } } } /// @notice Multiplies two unsigned 60.18-decimal fixed-point numbers together, returning a new unsigned 60.18-decimal /// fixed-point number. /// @dev See the documentation for the "PRBMath.mulDivFixedPoint" function. /// @param x The multiplicand as an unsigned 60.18-decimal fixed-point number. /// @param y The multiplier as an unsigned 60.18-decimal fixed-point number. /// @return result The product as an unsigned 60.18-decimal fixed-point number. function mul(uint256 x, uint256 y) internal pure returns (uint256 result) { result = PRBMath.mulDivFixedPoint(x, y); } /// @notice Returns PI as an unsigned 60.18-decimal fixed-point number. function pi() internal pure returns (uint256 result) { result = 3_141592653589793238; } /// @notice Raises x to the power of y. /// /// @dev Based on the insight that x^y = 2^(log2(x) * y). /// /// Requirements: /// - All from "exp2", "log2" and "mul". /// /// Caveats: /// - All from "exp2", "log2" and "mul". /// - Assumes 0^0 is 1. /// /// @param x Number to raise to given power y, as an unsigned 60.18-decimal fixed-point number. /// @param y Exponent to raise x to, as an unsigned 60.18-decimal fixed-point number. /// @return result x raised to power y, as an unsigned 60.18-decimal fixed-point number. function pow(uint256 x, uint256 y) internal pure returns (uint256 result) { if (x == 0) { result = y == 0 ? SCALE : uint256(0); } else { result = exp2(mul(log2(x), y)); } } /// @notice Raises x (unsigned 60.18-decimal fixed-point number) to the power of y (basic unsigned integer) using the /// famous algorithm "exponentiation by squaring". /// /// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring /// /// Requirements: /// - The result must fit within MAX_UD60x18. /// /// Caveats: /// - All from "mul". /// - Assumes 0^0 is 1. /// /// @param x The base as an unsigned 60.18-decimal fixed-point number. /// @param y The exponent as an uint256. /// @return result The result as an unsigned 60.18-decimal fixed-point number. function powu(uint256 x, uint256 y) internal pure returns (uint256 result) { // Calculate the first iteration of the loop in advance. result = y & 1 > 0 ? x : SCALE; // Equivalent to "for(y /= 2; y > 0; y /= 2)" but faster. for (y >>= 1; y > 0; y >>= 1) { x = PRBMath.mulDivFixedPoint(x, x); // Equivalent to "y % 2 == 1" but faster. if (y & 1 > 0) { result = PRBMath.mulDivFixedPoint(result, x); } } } /// @notice Returns 1 as an unsigned 60.18-decimal fixed-point number. function scale() internal pure returns (uint256 result) { result = SCALE; } /// @notice Calculates the square root of x, rounding down. /// @dev Uses the Babylonian method https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method. /// /// Requirements: /// - x must be less than MAX_UD60x18 / SCALE. /// /// @param x The unsigned 60.18-decimal fixed-point number for which to calculate the square root. /// @return result The result as an unsigned 60.18-decimal fixed-point . function sqrt(uint256 x) internal pure returns (uint256 result) { unchecked { if (x > MAX_UD60x18 / SCALE) { revert PRBMathUD60x18__SqrtOverflow(x); } // Multiply x by the SCALE to account for the factor of SCALE that is picked up when multiplying two unsigned // 60.18-decimal fixed-point numbers together (in this case, those two numbers are both the square root). result = PRBMath.sqrt(x * SCALE); } } /// @notice Converts a unsigned 60.18-decimal fixed-point number to basic integer form, rounding down in the process. /// @param x The unsigned 60.18-decimal fixed-point number to convert. /// @return result The same number in basic integer form. function toUint(uint256 x) internal pure returns (uint256 result) { unchecked { result = x / SCALE; } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.11; import "./ERC20.sol"; import "./WTF.sol"; import "./StakingRewards.sol"; contract FeeManager { WTF private wtf; constructor() { wtf = WTF(msg.sender); } function disburse() external { wtf.claimRewards(); uint256 _balance = wtf.balanceOf(address(this)); if (_balance > 0) { uint256 _oneFifth = _balance / 5; Treasury(payable(wtf.treasuryAddress())).collect(); wtf.transfer(wtf.treasuryAddress(), _oneFifth); // 20% StakingRewards(wtf.stakingRewardsAddress()).disburse(_oneFifth); // 20% StakingRewards(wtf.lpStakingRewardsAddress()).disburse(3 * _oneFifth); // 60% } } function wtfAddress() external view returns (address) { return address(wtf); } } contract TeamReferral { receive() external payable {} function release() external { address _this = address(this); require(_this.balance > 0); payable(0x6129E7bCb71C0d7D4580141C4E6a995f16293F42).transfer(_this.balance / 10); // 10% payable(0xc9AebdD8fD0d52c35A32fD9155467Cf28Ce474c3).transfer(_this.balance / 3); // 30% payable(0xdEE79eD62B42e30EA7EbB6f1b7A3f04143D18b7F).transfer(_this.balance / 2); // 30% payable(0x575446Aa9E9647C40edB7a467e45C5916add1538).transfer(_this.balance); // 30% } } contract Treasury { address public owner; uint256 public lockedUntil; WTF private wtf; modifier _onlyOwner() { require(msg.sender == owner); _; } constructor() { owner = 0x65dd4990719bE9B20322e4E8D3Bd77a4401a0357; lockedUntil = block.timestamp + 30 days; wtf = WTF(msg.sender); } receive() external payable {} function setOwner(address _owner) external _onlyOwner { owner = _owner; } function transferETH(address payable _destination, uint256 _amount) external _onlyOwner { require(isUnlocked()); _destination.transfer(_amount); } function transferTokens(ERC20 _token, address _destination, uint256 _amount) external _onlyOwner { require(isUnlocked()); _token.transfer(_destination, _amount); } function collect() external { wtf.claimRewards(); } function isUnlocked() public view returns (bool) { return block.timestamp > lockedUntil; } function wtfAddress() external view returns (address) { return address(wtf); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.11; import "./WTFNFT.sol"; import "./Treasury.sol"; import "./StakingRewards.sol"; interface Callable { function tokenCallback(address _from, uint256 _tokens, bytes calldata _data) external returns (bool); } interface Router { function WETH() external pure returns (address); function factory() external pure returns (address); } interface Factory { function createPair(address, address) external returns (address); } interface Pair { function token0() external view returns (address); function totalSupply() external view returns (uint256); function balanceOf(address) external view returns (uint256); function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); } contract WTF { uint256 constant private FLOAT_SCALAR = 2**64; uint256 constant private UINT_MAX = type(uint256).max; uint256 constant private TRANSFER_FEE_SCALE = 1000; // 1 = 0.1% uint256 constant private WTF_STAKING_SUPPLY = 2e25; // 20M WTF uint256 constant private LP_STAKING_SUPPLY = 4e25; // 40M WTF uint256 constant private TREASURY_SUPPLY = 4e25; // 40M WTF uint256 constant private BASE_UPGRADE_COST = 1e19; // 10 WTF uint256 constant private SERVICE_FEE = 0.01 ether; string constant public name = "fees.wtf"; string constant public symbol = "WTF"; uint8 constant public decimals = 18; struct User { uint256 balance; mapping(address => uint256) allowance; int256 scaledPayout; uint256 reflinkLevel; bool unlocked; } struct Info { bytes32 merkleRoot; uint256 openingTime; uint256 closingTime; uint256 totalSupply; uint256 scaledRewardsPerToken; mapping(uint256 => uint256) claimedWTFBitMap; mapping(uint256 => uint256) claimedNFTBitMap; mapping(address => User) users; mapping(address => bool) toWhitelist; mapping(address => bool) fromWhitelist; address owner; Router router; Pair pair; bool weth0; WTFNFT nft; TeamReferral team; Treasury treasury; StakingRewards stakingRewards; StakingRewards lpStakingRewards; address feeManager; uint256 transferFee; uint256 feeManagerPercent; } Info private info; event Transfer(address indexed from, address indexed to, uint256 tokens); event Approval(address indexed owner, address indexed spender, uint256 tokens); event WhitelistUpdated(address indexed user, bool fromWhitelisted, bool toWhitelisted); event ReflinkRewards(address indexed referrer, uint256 amount); event ClaimRewards(address indexed user, uint256 amount); event Reward(uint256 amount); modifier _onlyOwner() { require(msg.sender == owner()); _; } constructor(bytes32 _merkleRoot, uint256 _openingTime, uint256 _stakingRewardsStart) { info.merkleRoot = _merkleRoot; info.openingTime = block.timestamp < _openingTime ? _openingTime : block.timestamp; info.closingTime = openingTime() + 30 days; info.router = Router(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D); info.pair = Pair(Factory(info.router.factory()).createPair(info.router.WETH(), address(this))); info.weth0 = info.pair.token0() == info.router.WETH(); info.transferFee = 40; // 4% info.feeManagerPercent = 25; // 25% info.owner = 0x65dd4990719bE9B20322e4E8D3Bd77a4401a0357; info.nft = new WTFNFT(); info.team = new TeamReferral(); info.treasury = new Treasury(); _mint(treasuryAddress(), TREASURY_SUPPLY); info.stakingRewards = new StakingRewards(WTF_STAKING_SUPPLY, _stakingRewardsStart, ERC20(address(this))); _mint(stakingRewardsAddress(), WTF_STAKING_SUPPLY); info.lpStakingRewards = new StakingRewards(LP_STAKING_SUPPLY, _stakingRewardsStart, ERC20(pairAddress())); _mint(lpStakingRewardsAddress(), LP_STAKING_SUPPLY); info.feeManager = address(new FeeManager()); _approve(feeManagerAddress(), stakingRewardsAddress(), UINT_MAX); _approve(feeManagerAddress(), lpStakingRewardsAddress(), UINT_MAX); } function setOwner(address _owner) external _onlyOwner { info.owner = _owner; } function setFeeManager(address _feeManager) external _onlyOwner { info.feeManager = _feeManager; } function setClosingTime(uint256 _closingTime) external _onlyOwner { info.closingTime = _closingTime; } function setTransferFee(uint256 _transferFee) external _onlyOwner { require(_transferFee <= 100); // ≤10% info.transferFee = _transferFee; } function setFeeManagerPercent(uint256 _feeManagerPercent) external _onlyOwner { require(_feeManagerPercent <= 100); info.feeManagerPercent = _feeManagerPercent; } function setWhitelisted(address _address, bool _fromWhitelisted, bool _toWhitelisted) external _onlyOwner { info.fromWhitelist[_address] = _fromWhitelisted; info.toWhitelist[_address] = _toWhitelisted; emit WhitelistUpdated(_address, _fromWhitelisted, _toWhitelisted); } function disburse(uint256 _amount) external { require(_amount > 0); uint256 _balanceBefore = balanceOf(address(this)); _transfer(msg.sender, address(this), _amount); uint256 _amountReceived = balanceOf(address(this)) - _balanceBefore; _disburse(_amountReceived); } function sweep() external { if (address(this).balance > 0) { teamAddress().transfer(address(this).balance); } } function upgradeReflink(uint256 _toLevel) external { uint256 _currentLevel = reflinkLevel(msg.sender); require(_currentLevel < _toLevel); uint256 _totalCost = 0; for (uint256 i = _currentLevel; i < _toLevel; i++) { _totalCost += upgradeCost(i); } burn(_totalCost); info.users[msg.sender].reflinkLevel = _toLevel; } function unlock(address _account, address payable _referrer) external payable { require(block.timestamp < closingTime()); require(!isUnlocked(_account)); require(msg.value == SERVICE_FEE); uint256 _refFee = 0; if (_referrer != address(0x0)) { _refFee = SERVICE_FEE * reflinkPercent(_referrer) / 100; !_referrer.send(_refFee); emit ReflinkRewards(_referrer, _refFee); } uint256 _remaining = SERVICE_FEE - _refFee; teamAddress().transfer(_remaining); emit ReflinkRewards(teamAddress(), _remaining); info.users[_account].unlocked = true; } function claim(address _account, uint256[9] calldata _data, bytes32[] calldata _proof) external { // Data array in format: (index, amount, totalFees, failFees, totalGas, avgGwei, totalDonated, totalTxs, failTxs) claimWTF(_account, _data, _proof); claimNFT(_account, _data, _proof); } function claimWTF(address _account, uint256[9] calldata _data, bytes32[] calldata _proof) public { require(isOpen()); require(isUnlocked(_account)); uint256 _index = _data[0]; uint256 _amount = _data[1]; require(!isClaimedWTF(_index)); require(_verify(_proof, keccak256(abi.encodePacked(_account, _data)))); uint256 _claimedWordIndex = _index / 256; uint256 _claimedBitIndex = _index % 256; info.claimedWTFBitMap[_claimedWordIndex] = info.claimedWTFBitMap[_claimedWordIndex] | (1 << _claimedBitIndex); _mint(_account, _amount); } function claimNFT(address _account, uint256[9] calldata _data, bytes32[] calldata _proof) public { require(isOpen()); require(isUnlocked(_account)); uint256 _index = _data[0]; require(!isClaimedNFT(_index)); require(_verify(_proof, keccak256(abi.encodePacked(_account, _data)))); uint256 _claimedWordIndex = _index / 256; uint256 _claimedBitIndex = _index % 256; info.claimedNFTBitMap[_claimedWordIndex] = info.claimedNFTBitMap[_claimedWordIndex] | (1 << _claimedBitIndex); info.nft.mint(_account, _data[2], _data[3], _data[4], _data[5], _data[6], _data[7], _data[8]); } function claimRewards() external { boostRewards(); uint256 _rewards = rewardsOf(msg.sender); if (_rewards > 0) { info.users[msg.sender].scaledPayout += int256(_rewards * FLOAT_SCALAR); _transfer(address(this), msg.sender, _rewards); emit ClaimRewards(msg.sender, _rewards); } } function boostRewards() public { address _this = address(this); uint256 _rewards = rewardsOf(_this); if (_rewards > 0) { info.users[_this].scaledPayout += int256(_rewards * FLOAT_SCALAR); _disburse(_rewards); emit ClaimRewards(_this, _rewards); } } function burn(uint256 _tokens) public { require(balanceOf(msg.sender) >= _tokens); info.totalSupply -= _tokens; info.users[msg.sender].balance -= _tokens; info.users[msg.sender].scaledPayout -= int256(_tokens * info.scaledRewardsPerToken); emit Transfer(msg.sender, address(0x0), _tokens); } function transfer(address _to, uint256 _tokens) external returns (bool) { return _transfer(msg.sender, _to, _tokens); } function approve(address _spender, uint256 _tokens) external returns (bool) { return _approve(msg.sender, _spender, _tokens); } function transferFrom(address _from, address _to, uint256 _tokens) external returns (bool) { uint256 _allowance = allowance(_from, msg.sender); require(_allowance >= _tokens); if (_allowance != UINT_MAX) { info.users[_from].allowance[msg.sender] -= _tokens; } return _transfer(_from, _to, _tokens); } function transferAndCall(address _to, uint256 _tokens, bytes calldata _data) external returns (bool) { uint256 _balanceBefore = balanceOf(_to); _transfer(msg.sender, _to, _tokens); uint256 _tokensReceived = balanceOf(_to) - _balanceBefore; uint32 _size; assembly { _size := extcodesize(_to) } if (_size > 0) { require(Callable(_to).tokenCallback(msg.sender, _tokensReceived, _data)); } return true; } function pairAddress() public view returns (address) { return address(info.pair); } function nftAddress() external view returns (address) { return address(info.nft); } function teamAddress() public view returns (address payable) { return payable(address(info.team)); } function treasuryAddress() public view returns (address) { return address(info.treasury); } function stakingRewardsAddress() public view returns (address) { return address(info.stakingRewards); } function lpStakingRewardsAddress() public view returns (address) { return address(info.lpStakingRewards); } function feeManagerAddress() public view returns (address) { return info.feeManager; } function owner() public view returns (address) { return info.owner; } function transferFee() public view returns (uint256) { return info.transferFee; } function feeManagerPercent() public view returns (uint256) { return info.feeManagerPercent; } function isFromWhitelisted(address _address) public view returns (bool) { return info.fromWhitelist[_address]; } function isToWhitelisted(address _address) public view returns (bool) { return info.toWhitelist[_address]; } function merkleRoot() public view returns (bytes32) { return info.merkleRoot; } function openingTime() public view returns (uint256) { return info.openingTime; } function closingTime() public view returns (uint256) { return info.closingTime; } function isOpen() public view returns (bool) { return block.timestamp > openingTime() && block.timestamp < closingTime(); } function isUnlocked(address _user) public view returns (bool) { return info.users[_user].unlocked; } function isClaimedWTF(uint256 _index) public view returns (bool) { uint256 _claimedWordIndex = _index / 256; uint256 _claimedBitIndex = _index % 256; uint256 _claimedWord = info.claimedWTFBitMap[_claimedWordIndex]; uint256 _mask = (1 << _claimedBitIndex); return _claimedWord & _mask == _mask; } function isClaimedNFT(uint256 _index) public view returns (bool) { uint256 _claimedWordIndex = _index / 256; uint256 _claimedBitIndex = _index % 256; uint256 _claimedWord = info.claimedNFTBitMap[_claimedWordIndex]; uint256 _mask = (1 << _claimedBitIndex); return _claimedWord & _mask == _mask; } function totalSupply() public view returns (uint256) { return info.totalSupply; } function balanceOf(address _user) public view returns (uint256) { return info.users[_user].balance; } function rewardsOf(address _user) public view returns (uint256) { return uint256(int256(info.scaledRewardsPerToken * balanceOf(_user)) - info.users[_user].scaledPayout) / FLOAT_SCALAR; } function allowance(address _user, address _spender) public view returns (uint256) { return info.users[_user].allowance[_spender]; } function reflinkLevel(address _user) public view returns (uint256) { return info.users[_user].reflinkLevel; } function reflinkPercent(address _user) public view returns (uint256) { return 10 * (reflinkLevel(_user) + 1); } function upgradeCost(uint256 _reflinkLevel) public pure returns (uint256) { require(_reflinkLevel < 4); return BASE_UPGRADE_COST * 10**_reflinkLevel; } function reflinkInfoFor(address _user) external view returns (uint256 balance, uint256 level, uint256 percent) { return (balanceOf(_user), reflinkLevel(_user), reflinkPercent(_user)); } function claimInfoFor(uint256 _index, address _user) external view returns (uint256 openTime, uint256 closeTime, bool unlocked, bool claimedWTF, bool claimedNFT, uint256 wethReserve, uint256 wtfReserve) { openTime = openingTime(); closeTime = closingTime(); unlocked = isUnlocked(_user); claimedWTF = isClaimedWTF(_index); claimedNFT = isClaimedNFT(_index); ( , , wethReserve, wtfReserve, , , ) = allInfoFor(address(0x0)); } function allInfoFor(address _user) public view returns (uint256 totalTokens, uint256 totalLPTokens, uint256 wethReserve, uint256 wtfReserve, uint256 userBalance, uint256 userRewards, uint256 userLPBalance) { totalTokens = totalSupply(); totalLPTokens = info.pair.totalSupply(); (uint256 _res0, uint256 _res1, ) = info.pair.getReserves(); wethReserve = info.weth0 ? _res0 : _res1; wtfReserve = info.weth0 ? _res1 : _res0; userBalance = balanceOf(_user); userRewards = rewardsOf(_user); userLPBalance = info.pair.balanceOf(_user); } function _mint(address _account, uint256 _amount) internal { info.totalSupply += _amount; info.users[_account].balance += _amount; info.users[_account].scaledPayout += int256(_amount * info.scaledRewardsPerToken); emit Transfer(address(0x0), _account, _amount); } function _approve(address _owner, address _spender, uint256 _tokens) internal returns (bool) { info.users[_owner].allowance[_spender] = _tokens; emit Approval(_owner, _spender, _tokens); return true; } function _transfer(address _from, address _to, uint256 _tokens) internal returns (bool) { require(balanceOf(_from) >= _tokens); info.users[_from].balance -= _tokens; info.users[_from].scaledPayout -= int256(_tokens * info.scaledRewardsPerToken); uint256 _fee = 0; if (!_isExcludedFromFee(_from, _to)) { _fee = _tokens * transferFee() / TRANSFER_FEE_SCALE; address _this = address(this); info.users[_this].balance += _fee; info.users[_this].scaledPayout += int256(_fee * info.scaledRewardsPerToken); emit Transfer(_from, _this, _fee); } uint256 _transferred = _tokens - _fee; info.users[_to].balance += _transferred; info.users[_to].scaledPayout += int256(_transferred * info.scaledRewardsPerToken); emit Transfer(_from, _to, _transferred); if (_fee > 0) { uint256 _feeManagerRewards = _fee * feeManagerPercent() / 100; info.users[feeManagerAddress()].scaledPayout -= int256(_feeManagerRewards * FLOAT_SCALAR); _disburse(_fee - _feeManagerRewards); } return true; } function _disburse(uint256 _amount) internal { if (_amount > 0) { info.scaledRewardsPerToken += _amount * FLOAT_SCALAR / totalSupply(); emit Reward(_amount); } } function _isExcludedFromFee(address _from, address _to) internal view returns (bool) { return isFromWhitelisted(_from) || isToWhitelisted(_to) || _from == address(this) || _to == address(this) || _from == feeManagerAddress() || _to == feeManagerAddress() || _from == treasuryAddress() || _to == treasuryAddress() || _from == stakingRewardsAddress() || _to == stakingRewardsAddress() || _from == lpStakingRewardsAddress() || _to == lpStakingRewardsAddress(); } function _verify(bytes32[] memory _proof, bytes32 _leaf) internal view returns (bool) { bytes32 _computedHash = _leaf; for (uint256 i = 0; i < _proof.length; i++) { bytes32 _proofElement = _proof[i]; if (_computedHash <= _proofElement) { _computedHash = keccak256(abi.encodePacked(_computedHash, _proofElement)); } else { _computedHash = keccak256(abi.encodePacked(_proofElement, _computedHash)); } } return _computedHash == merkleRoot(); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.11; import "./Metadata.sol"; interface Receiver { function onERC721Received(address _operator, address _from, uint256 _tokenId, bytes calldata _data) external returns (bytes4); } contract WTFNFT { struct User { uint256 balance; mapping(uint256 => uint256) list; mapping(address => bool) approved; mapping(uint256 => uint256) indexOf; uint256 tokenIndex; } struct Token { address user; address owner; address approved; uint128 totalFees; uint128 failFees; uint128 totalGas; uint128 avgGwei; uint128 totalDonated; uint64 totalTxs; uint64 failTxs; } struct Info { uint256 totalSupply; mapping(uint256 => Token) list; mapping(address => User) users; Metadata metadata; address wtf; address owner; } Info private info; mapping(bytes4 => bool) public supportsInterface; event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); event ApprovalForAll(address indexed owner, address indexed operator, bool approved); event Mint(address indexed owner, uint256 indexed tokenId, uint256 totalFees, uint256 failFees, uint256 totalGas, uint256 avgGwei, uint256 totalDonated, uint256 totalTxs, uint256 failTxs); modifier _onlyOwner() { require(msg.sender == owner()); _; } constructor() { info.metadata = new Metadata(this); info.wtf = msg.sender; info.owner = 0xdEE79eD62B42e30EA7EbB6f1b7A3f04143D18b7F; supportsInterface[0x01ffc9a7] = true; // ERC-165 supportsInterface[0x80ac58cd] = true; // ERC-721 supportsInterface[0x5b5e139f] = true; // Metadata supportsInterface[0x780e9d63] = true; // Enumerable } function setOwner(address _owner) external _onlyOwner { info.owner = _owner; } function setMetadata(Metadata _metadata) external _onlyOwner { info.metadata = _metadata; } function mint(address _receiver, uint256 _totalFees, uint256 _failFees, uint256 _totalGas, uint256 _avgGwei, uint256 _totalDonated, uint256 _totalTxs, uint256 _failTxs) public { require(msg.sender == wtfAddress()); uint256 _tokenId = info.totalSupply++; info.users[_receiver].tokenIndex = totalSupply(); Token storage _newToken = info.list[_tokenId]; _newToken.user = _receiver; _newToken.owner = _receiver; _newToken.totalFees = uint128(_totalFees); _newToken.failFees = uint128(_failFees); _newToken.totalGas = uint128(_totalGas); _newToken.avgGwei = uint128(_avgGwei); _newToken.totalDonated = uint128(_totalDonated); _newToken.totalTxs = uint64(_totalTxs); _newToken.failTxs = uint64(_failTxs); uint256 _index = info.users[_receiver].balance++; info.users[_receiver].indexOf[_tokenId] = _index + 1; info.users[_receiver].list[_index] = _tokenId; emit Transfer(address(0x0), _receiver, _tokenId); emit Mint(_receiver, _tokenId, _totalFees, _failFees, _totalGas, _avgGwei, _totalDonated, _totalTxs, _failTxs); } function approve(address _approved, uint256 _tokenId) external { require(msg.sender == ownerOf(_tokenId)); info.list[_tokenId].approved = _approved; emit Approval(msg.sender, _approved, _tokenId); } function setApprovalForAll(address _operator, bool _approved) external { info.users[msg.sender].approved[_operator] = _approved; emit ApprovalForAll(msg.sender, _operator, _approved); } function transferFrom(address _from, address _to, uint256 _tokenId) external { _transfer(_from, _to, _tokenId); } function safeTransferFrom(address _from, address _to, uint256 _tokenId) external { safeTransferFrom(_from, _to, _tokenId, ""); } function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes memory _data) public { _transfer(_from, _to, _tokenId); uint32 _size; assembly { _size := extcodesize(_to) } if (_size > 0) { require(Receiver(_to).onERC721Received(msg.sender, _from, _tokenId, _data) == 0x150b7a02); } } function name() external view returns (string memory) { return info.metadata.name(); } function symbol() external view returns (string memory) { return info.metadata.symbol(); } function tokenURI(uint256 _tokenId) external view returns (string memory) { return info.metadata.tokenURI(_tokenId); } function metadataAddress() public view returns (address) { return address(info.metadata); } function wtfAddress() public view returns (address) { return info.wtf; } function owner() public view returns (address) { return info.owner; } function totalSupply() public view returns (uint256) { return info.totalSupply; } function balanceOf(address _owner) public view returns (uint256) { return info.users[_owner].balance; } function ownerOf(uint256 _tokenId) public view returns (address) { require(_tokenId < totalSupply()); return info.list[_tokenId].owner; } function getUser(uint256 _tokenId) public view returns (address) { require(_tokenId < totalSupply()); return info.list[_tokenId].user; } function getApproved(uint256 _tokenId) public view returns (address) { require(_tokenId < totalSupply()); return info.list[_tokenId].approved; } function getTotalFees(uint256 _tokenId) public view returns (uint256) { require(_tokenId < totalSupply()); return info.list[_tokenId].totalFees; } function getFailFees(uint256 _tokenId) public view returns (uint256) { require(_tokenId < totalSupply()); return info.list[_tokenId].failFees; } function getTotalGas(uint256 _tokenId) public view returns (uint256) { require(_tokenId < totalSupply()); return info.list[_tokenId].totalGas; } function getAvgGwei(uint256 _tokenId) public view returns (uint256) { require(_tokenId < totalSupply()); return info.list[_tokenId].avgGwei; } function getTotalDonated(uint256 _tokenId) public view returns (uint256) { require(_tokenId < totalSupply()); return info.list[_tokenId].totalDonated; } function getTotalTxs(uint256 _tokenId) public view returns (uint256) { require(_tokenId < totalSupply()); return info.list[_tokenId].totalTxs; } function getFailTxs(uint256 _tokenId) public view returns (uint256) { require(_tokenId < totalSupply()); return info.list[_tokenId].failTxs; } function isApprovedForAll(address _owner, address _operator) public view returns (bool) { return info.users[_owner].approved[_operator]; } function tokenIdOf(address _user) public view returns (uint256) { uint256 _index = info.users[_user].tokenIndex; require(_index > 0); return _index - 1; } function tokenByIndex(uint256 _index) public view returns (uint256) { require(_index < totalSupply()); return _index; } function tokenOfOwnerByIndex(address _owner, uint256 _index) public view returns (uint256) { require(_index < balanceOf(_owner)); return info.users[_owner].list[_index]; } function getTokenCompressedInfo(uint256 _tokenId) public view returns (uint256[7] memory compressedInfo) { compressedInfo[0] = getTotalFees(_tokenId); compressedInfo[1] = getFailFees(_tokenId); compressedInfo[2] = getTotalGas(_tokenId); compressedInfo[3] = getAvgGwei(_tokenId); compressedInfo[4] = getTotalDonated(_tokenId); compressedInfo[5] = getTotalTxs(_tokenId); compressedInfo[6] = getFailTxs(_tokenId); } function getToken(uint256 _tokenId) public view returns (address tokenOwner, address approved, address user, uint256[7] memory compressedInfo) { return (ownerOf(_tokenId), getApproved(_tokenId), getUser(_tokenId), getTokenCompressedInfo(_tokenId)); } function getTokens(uint256[] memory _tokenIds) public view returns (address[] memory owners, address[] memory approveds, address[] memory users, uint256[7][] memory compressedInfos) { uint256 _length = _tokenIds.length; owners = new address[](_length); approveds = new address[](_length); users = new address[](_length); compressedInfos = new uint256[7][](_length); for (uint256 i = 0; i < _length; i++) { (owners[i], approveds[i], users[i], compressedInfos[i]) = getToken(_tokenIds[i]); } } function getTokensTable(uint256 _limit, uint256 _page, bool _isAsc) public view returns (uint256[] memory tokenIds, address[] memory owners, address[] memory approveds, address[] memory users, uint256[7][] memory compressedInfos, uint256 totalTokens, uint256 totalPages) { require(_limit > 0); totalTokens = totalSupply(); if (totalTokens > 0) { totalPages = (totalTokens / _limit) + (totalTokens % _limit == 0 ? 0 : 1); require(_page < totalPages); uint256 _offset = _limit * _page; if (_page == totalPages - 1 && totalTokens % _limit != 0) { _limit = totalTokens % _limit; } tokenIds = new uint256[](_limit); for (uint256 i = 0; i < _limit; i++) { tokenIds[i] = tokenByIndex(_isAsc ? _offset + i : totalTokens - _offset - i - 1); } } else { totalPages = 0; tokenIds = new uint256[](0); } (owners, approveds, users, compressedInfos) = getTokens(tokenIds); } function getOwnerTokensTable(address _owner, uint256 _limit, uint256 _page, bool _isAsc) public view returns (uint256[] memory tokenIds, address[] memory approveds, address[] memory users, uint256[7][] memory compressedInfos, uint256 totalTokens, uint256 totalPages) { require(_limit > 0); totalTokens = balanceOf(_owner); if (totalTokens > 0) { totalPages = (totalTokens / _limit) + (totalTokens % _limit == 0 ? 0 : 1); require(_page < totalPages); uint256 _offset = _limit * _page; if (_page == totalPages - 1 && totalTokens % _limit != 0) { _limit = totalTokens % _limit; } tokenIds = new uint256[](_limit); for (uint256 i = 0; i < _limit; i++) { tokenIds[i] = tokenOfOwnerByIndex(_owner, _isAsc ? _offset + i : totalTokens - _offset - i - 1); } } else { totalPages = 0; tokenIds = new uint256[](0); } ( , approveds, users, compressedInfos) = getTokens(tokenIds); } function allInfoFor(address _owner) external view returns (uint256 supply, uint256 ownerBalance) { return (totalSupply(), balanceOf(_owner)); } function _transfer(address _from, address _to, uint256 _tokenId) internal { address _owner = ownerOf(_tokenId); address _approved = getApproved(_tokenId); require(_from == _owner); require(msg.sender == _owner || msg.sender == _approved || isApprovedForAll(_owner, msg.sender)); info.list[_tokenId].owner = _to; if (_approved != address(0x0)) { info.list[_tokenId].approved = address(0x0); emit Approval(address(0x0), address(0x0), _tokenId); } uint256 _index = info.users[_from].indexOf[_tokenId] - 1; uint256 _moved = info.users[_from].list[info.users[_from].balance - 1]; info.users[_from].list[_index] = _moved; info.users[_from].indexOf[_moved] = _index + 1; info.users[_from].balance--; delete info.users[_from].indexOf[_tokenId]; uint256 _newIndex = info.users[_to].balance++; info.users[_to].indexOf[_tokenId] = _newIndex + 1; info.users[_to].list[_newIndex] = _tokenId; emit Transfer(_from, _to, _tokenId); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"uint256","name":"_totalRewards","type":"uint256"},{"internalType":"uint256","name":"_stakingRewardsStart","type":"uint256"},{"internalType":"contract ERC20","name":"_token","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"}],"name":"PRBMathUD60x18__Exp2InputTooBig","type":"error"},{"inputs":[{"internalType":"uint256","name":"prod1","type":"uint256"}],"name":"PRBMath__MulDivFixedPointOverflow","type":"error"},{"inputs":[{"internalType":"uint256","name":"prod1","type":"uint256"},{"internalType":"uint256","name":"denominator","type":"uint256"}],"name":"PRBMath__MulDivOverflow","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Claim","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Reinvest","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Reward","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"allInfoFor","outputs":[{"internalType":"uint256","name":"startingTime","type":"uint256"},{"internalType":"uint256","name":"totalRewardsDistributed","type":"uint256"},{"internalType":"uint256","name":"rewardsRatePerDay","type":"uint256"},{"internalType":"uint256","name":"currentFeePercent","type":"uint256"},{"internalType":"uint256","name":"totalTokensDeposited","type":"uint256"},{"internalType":"uint256","name":"virtualRewards","type":"uint256"},{"internalType":"uint256","name":"userWTF","type":"uint256"},{"internalType":"uint256","name":"userBalance","type":"uint256"},{"internalType":"uint256","name":"userAllowance","type":"uint256"},{"internalType":"uint256","name":"userDeposited","type":"uint256"},{"internalType":"uint256","name":"userRewards","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"currentRatePerDay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"depositFor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"depositedOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"disburse","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reinvest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"rewardsOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"startTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint256","name":"_tokens","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"tokenCallback","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalDeposited","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalDistributed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"update","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"wtfAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b5060405162001d4e38038062001d4e83398101604081905261003191610083565b60008390554282116100435742610045565b815b600181905560025560078054336001600160a01b031991821617909155600880549091166001600160a01b0392909216919091179055506100c99050565b60008060006060848603121561009857600080fd5b83516020850151604086015191945092506001600160a01b03811681146100be57600080fd5b809150509250925092565b611c7580620000d96000396000f3fe608060405234801561001057600080fd5b50600436106101165760003560e01c8063853828b6116100a2578063b6b55f2511610071578063b6b55f2514610279578063bd77ac2c1461028c578063efca2eed1461029f578063fdb5a03e146102a7578063ff50abdc146102af57600080fd5b8063853828b6146102505780639d76ea5814610258578063a2e6204514610269578063a9045fec1461027157600080fd5b806357f6b812116100e957806357f6b812146101715780635c99d8cc146101d75780636be32e73146102005780636ff92f501461022357806378e979251461024857600080fd5b80632e1a7d4d1461011b5780632f4f21e214610130578063479ba7ae146101435780634e71d92d14610169575b600080fd5b61012e6101293660046119e7565b6102b7565b005b61012e61013e366004611a1c565b61043c565b610156610151366004611a46565b6105c8565b6040519081526020015b60405180910390f35b61012e610614565b61018461017f366004611a46565b610714565b604080519b8c5260208c019a909a52988a01979097526060890195909552608088019390935260a087019190915260c086015260e085015261010084015261012083015261014082015261016001610160565b6101566101e5366004611a46565b6001600160a01b031660009081526006602052604090205490565b61021361020e366004611a61565b610932565b6040519015158152602001610160565b6007546001600160a01b03165b6040516001600160a01b039091168152602001610160565b600154610156565b61012e610985565b6008546001600160a01b0316610230565b61012e6109a4565b610156610b68565b61012e6102873660046119e7565b610bce565b61012e61029a3660046119e7565b610bd8565b610156610d5d565b61012e610d73565b600554610156565b6000811180156102d65750336000908152600660205260409020548111155b6102df57600080fd5b6102e76109a4565b80600060050160008282546102fc9190611afe565b90915550503360009081526006602052604081208054839290610320908490611afe565b90915550506004546103329082611b15565b3360009081526006602052604081206001018054909190610354908490611b34565b909155506000905061036582610e11565b6008549091506001600160a01b031663a9059cbb336103848486611afe565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af11580156103cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103f39190611b73565b506103fd81610e64565b604080518381526020810183905233917ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b568910160405180910390a25050565b6000811161044957600080fd5b6104516109a4565b6008546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa15801561049a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104be9190611b95565b6008546040516323b872dd60e01b8152336004820152306024820152604481018590529192506001600160a01b0316906323b872dd906064016020604051808303816000875af1158015610516573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061053a9190611b73565b506008546040516370a0823160e01b815230600482015260009183916001600160a01b03909116906370a0823190602401602060405180830381865afa158015610588573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ac9190611b95565b6105b69190611afe565b90506105c28482610ea8565b50505050565b6001600160a01b038116600090815260066020526040812060018101549054600454600160401b92916105fa91611b15565b6106049190611b34565b61060e9190611bc4565b92915050565b61061c6109a4565b6000610627336105c8565b905080156107115761063d600160401b82611b15565b336000908152600660205260408120600101805490919061065f908490611be6565b909155505060075460405163a9059cbb60e01b8152336004820152602481018390526001600160a01b039091169063a9059cbb906044016020604051808303816000875af11580156106b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106d99190611b73565b5060405181815233907f47cee97cb7acd717b3c0aa1435d004cd5b3c8c57d70dbceb4e4458bbd60e39d4906020015b60405180910390a25b50565b600080600080600080600080600080600061072e60015490565b9a50610738610d5d565b9950610742610b68565b985061075668056bc75e2d63100000610e11565b975061076160055490565b600254909750421161077457600061079f565b61079f610796610788600060020154610f9b565b61079142610f9b565b610ffb565b60005490611026565b6007546040516370a0823160e01b81526001600160a01b038f811660048301529298509116906370a0823190602401602060405180830381865afa1580156107eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061080f9190611b95565b6008546040516370a0823160e01b81526001600160a01b038f811660048301529297509116906370a0823190602401602060405180830381865afa15801561085b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061087f9190611b95565b600854604051636eb1769f60e11b81526001600160a01b038f8116600483015230602483015292965091169063dd62ed3e90604401602060405180830381865afa1580156108d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f59190611b95565b92506109168c6001600160a01b031660009081526006602052604090205490565b91506109218c6105c8565b905091939597999b90929496989a50565b600061093c611032565b801561095257506008546001600160a01b031633145b61095b57600080fd5b6000841161096857600080fd5b6109706109a4565b61097a8585610ea8565b506001949350505050565b33600090815260066020526040902054801561071157610711816102b7565b6002544290811180156109bf575060006109bd60055490565b115b156107115760006109e36107966109da600060020154610f9b565b61079185610f9b565b60035490915015610a03576003546109fb9082611c27565b600060035590505b6007546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015610a4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a709190611b95565b6007546040805163372500ab60e01b815290519293506001600160a01b039091169163372500ab9160048082019260009290919082900301818387803b158015610ab957600080fd5b505af1158015610acd573d6000803e3d6000fd5b50506007546040516370a0823160e01b81523060048201528493506001600160a01b0390911691506370a0823190602401602060405180830381865afa158015610b1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3f9190611b95565b610b499190611afe565b610b539083611c27565b60028490559150610b6382611070565b505050565b6000610b7360015490565b421015610baf57610baa610796610b91610b8c60015490565b610f9b565b610791610b9d60015490565b610b8c9062015180611c27565b905090565b610baa610796610bbe42610f9b565b610791610b8c4262015180611c27565b610711338261043c565b60008111610be557600080fd5b610bed6109a4565b6007546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015610c36573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5a9190611b95565b6007546040516323b872dd60e01b8152336004820152306024820152604481018590529192506001600160a01b0316906323b872dd906064016020604051808303816000875af1158015610cb2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cd69190611b73565b506007546040516370a0823160e01b815230600482015260009183916001600160a01b03909116906370a0823190602401602060405180830381865afa158015610d24573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d489190611b95565b610d529190611afe565b9050610b6381610e64565b6000610baa610796610d6e42610f9b565b6110d8565b610d7b611032565b610d8457600080fd5b610d8c6109a4565b6000610d97336105c8565b9050801561071157610dad600160401b82611b15565b3360009081526006602052604081206001018054909190610dcf908490611be6565b90915550610ddf90503382610ea8565b60405181815233907fbd654390d0d973e8c8376ed6053be8658870df892687852cc5c914d700291b8790602001610708565b6000610e1b611032565b610e2657600061060e565b61060e610e35610d6e42610f9b565b610e4790670de0b6b3a7640000611afe565b6064610e54600586611b15565b610e5e9190611bc4565b90611026565b801561071157600154421080610e7a5750600554155b15610e9f578060006003016000828254610e949190611c27565b909155506107119050565b61071181611070565b6000610eb382610e11565b90506000610ec18284611afe565b90508060006005016000828254610ed89190611c27565b90915550506001600160a01b03841660009081526006602052604081208054839290610f05908490611c27565b9091555050600454610f179082611b15565b6001600160a01b03851660009081526006602052604081206001018054909190610f42908490611be6565b90915550610f51905082610e64565b60408051848152602081018490526001600160a01b038616917f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a15910160405180910390a250505050565b600080610fa760015490565b905080831015610fba5750600092915050565b610ff4610fd262278d00670de0b6b3a7640000611b15565b610fdc8386611afe565b610fee90670de0b6b3a7640000611b15565b906110fc565b9392505050565b60008282101561100a57600080fd5b611013836110d8565b61101c836110d8565b610ff49190611afe565b6000610ff48383611111565b60006110466008546001600160a01b031690565b6001600160a01b03166110616007546001600160a01b031690565b6001600160a01b031614905090565b600554611081600160401b83611b15565b61108b9190611bc4565b6004805460009061109d908490611c27565b90915550506040518181527f3ac0594a85a20354f9dc74f33728416d19ce00d04a406c108cc2dcf2cecea1349060200160405180910390a150565b6000806110e4836111d8565b9050610ff481610fee670de0b6b3a764000082611afe565b6000610ff483670de0b6b3a76400008461121e565b60008080600019848609848602925082811083820303915050670de0b6b3a7640000811061115a5760405163698d9a0160e11b8152600481018290526024015b60405180910390fd5b600080670de0b6b3a76400008688099150506706f05b59d3b1ffff8111826111945780670de0b6b3a764000085040194505050505061060e565b620400008285030493909111909103600160ee1b02919091177faccb18165bd6fe31ae1cf318dc5b51eee0e1ba569b88cd74c1773b91fac106690201905092915050565b6000680a688906bd8b000000821061120657604051634a4f26f160e01b815260048101839052602401611151565b670de0b6b3a7640000604083901b04610ff4816112eb565b6000808060001985870985870292508281108382030391505080600014156112595783828161124f5761124f611bae565b0492505050610ff4565b83811061128357604051631dcf306360e21b81526004810182905260248101859052604401611151565b600084868809600260036001881981018916988990049182028318808302840302808302840302808302840302808302840302808302840302918202909203026000889003889004909101858311909403939093029303949094049190911702949350505050565b600160bf1b67800000000000000082161561130f5768016a09e667f3bcc9090260401c5b67400000000000000082161561132e576801306fe0a31b7152df0260401c5b67200000000000000082161561134d576801172b83c7d517adce0260401c5b67100000000000000082161561136c5768010b5586cf9890f62a0260401c5b67080000000000000082161561138b576801059b0d31585743ae0260401c5b6704000000000000008216156113aa57680102c9a3e778060ee70260401c5b6702000000000000008216156113c95768010163da9fb33356d80260401c5b6701000000000000008216156113e857680100b1afa5abcbed610260401c5b66800000000000008216156114065768010058c86da1c09ea20260401c5b6640000000000000821615611424576801002c605e2e8cec500260401c5b662000000000000082161561144257680100162f3904051fa10260401c5b6610000000000000821615611460576801000b175effdc76ba0260401c5b660800000000000082161561147e57680100058ba01fb9f96d0260401c5b660400000000000082161561149c5768010002c5cc37da94920260401c5b66020000000000008216156114ba576801000162e525ee05470260401c5b66010000000000008216156114d85768010000b17255775c040260401c5b658000000000008216156114f5576801000058b91b5bc9ae0260401c5b6540000000000082161561151257680100002c5c89d5ec6d0260401c5b6520000000000082161561152f5768010000162e43f4f8310260401c5b6510000000000082161561154c57680100000b1721bcfc9a0260401c5b650800000000008216156115695768010000058b90cf1e6e0260401c5b65040000000000821615611586576801000002c5c863b73f0260401c5b650200000000008216156115a357680100000162e430e5a20260401c5b650100000000008216156115c0576801000000b1721835510260401c5b6480000000008216156115dc57680100000058b90c0b490260401c5b6440000000008216156115f85768010000002c5c8601cc0260401c5b642000000000821615611614576801000000162e42fff00260401c5b6410000000008216156116305768010000000b17217fbb0260401c5b64080000000082161561164c576801000000058b90bfce0260401c5b64040000000082161561166857680100000002c5c85fe30260401c5b6402000000008216156116845768010000000162e42ff10260401c5b6401000000008216156116a057680100000000b17217f80260401c5b63800000008216156116bb5768010000000058b90bfc0260401c5b63400000008216156116d6576801000000002c5c85fe0260401c5b63200000008216156116f157680100000000162e42ff0260401c5b631000000082161561170c576801000000000b17217f0260401c5b630800000082161561172757680100000000058b90c00260401c5b63040000008216156117425768010000000002c5c8600260401c5b630200000082161561175d576801000000000162e4300260401c5b63010000008216156117785768010000000000b172180260401c5b62800000821615611792576801000000000058b90c0260401c5b624000008216156117ac57680100000000002c5c860260401c5b622000008216156117c65768010000000000162e430260401c5b621000008216156117e057680100000000000b17210260401c5b620800008216156117fa5768010000000000058b910260401c5b62040000821615611814576801000000000002c5c80260401c5b6202000082161561182e57680100000000000162e40260401c5b62010000821615611848576801000000000000b1720260401c5b61800082161561186157680100000000000058b90260401c5b61400082161561187a5768010000000000002c5d0260401c5b612000821615611893576801000000000000162e0260401c5b6110008216156118ac5768010000000000000b170260401c5b6108008216156118c5576801000000000000058c0260401c5b6104008216156118de57680100000000000002c60260401c5b6102008216156118f757680100000000000001630260401c5b61010082161561191057680100000000000000b10260401c5b608082161561192857680100000000000000590260401c5b6040821615611940576801000000000000002c0260401c5b602082161561195857680100000000000000160260401c5b6010821615611970576801000000000000000b0260401c5b600882161561198857680100000000000000060260401c5b60048216156119a057680100000000000000030260401c5b60028216156119b857680100000000000000010260401c5b60018216156119d057680100000000000000010260401c5b670de0b6b3a76400000260409190911c60bf031c90565b6000602082840312156119f957600080fd5b5035919050565b80356001600160a01b0381168114611a1757600080fd5b919050565b60008060408385031215611a2f57600080fd5b611a3883611a00565b946020939093013593505050565b600060208284031215611a5857600080fd5b610ff482611a00565b60008060008060608587031215611a7757600080fd5b611a8085611a00565b935060208501359250604085013567ffffffffffffffff80821115611aa457600080fd5b818701915087601f830112611ab857600080fd5b813581811115611ac757600080fd5b886020828501011115611ad957600080fd5b95989497505060200194505050565b634e487b7160e01b600052601160045260246000fd5b600082821015611b1057611b10611ae8565b500390565b6000816000190483118215151615611b2f57611b2f611ae8565b500290565b60008083128015600160ff1b850184121615611b5257611b52611ae8565b6001600160ff1b0384018313811615611b6d57611b6d611ae8565b50500390565b600060208284031215611b8557600080fd5b81518015158114610ff457600080fd5b600060208284031215611ba757600080fd5b5051919050565b634e487b7160e01b600052601260045260246000fd5b600082611be157634e487b7160e01b600052601260045260246000fd5b500490565b600080821280156001600160ff1b0384900385131615611c0857611c08611ae8565b600160ff1b8390038412811615611c2157611c21611ae8565b50500190565b60008219821115611c3a57611c3a611ae8565b50019056fea264697066735822122085ab3ecdd07e5de48258a7e7b79867e88425d9b2f19e550dd19f024e9e9d633964736f6c634300080b0033000000000000000000000000000000000000000000108b2a2c280290940000000000000000000000000000000000000000000000000000000000000061e20e80000000000000000000000000a68dd8cb83097765263adad881af6eed479c4a33
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101165760003560e01c8063853828b6116100a2578063b6b55f2511610071578063b6b55f2514610279578063bd77ac2c1461028c578063efca2eed1461029f578063fdb5a03e146102a7578063ff50abdc146102af57600080fd5b8063853828b6146102505780639d76ea5814610258578063a2e6204514610269578063a9045fec1461027157600080fd5b806357f6b812116100e957806357f6b812146101715780635c99d8cc146101d75780636be32e73146102005780636ff92f501461022357806378e979251461024857600080fd5b80632e1a7d4d1461011b5780632f4f21e214610130578063479ba7ae146101435780634e71d92d14610169575b600080fd5b61012e6101293660046119e7565b6102b7565b005b61012e61013e366004611a1c565b61043c565b610156610151366004611a46565b6105c8565b6040519081526020015b60405180910390f35b61012e610614565b61018461017f366004611a46565b610714565b604080519b8c5260208c019a909a52988a01979097526060890195909552608088019390935260a087019190915260c086015260e085015261010084015261012083015261014082015261016001610160565b6101566101e5366004611a46565b6001600160a01b031660009081526006602052604090205490565b61021361020e366004611a61565b610932565b6040519015158152602001610160565b6007546001600160a01b03165b6040516001600160a01b039091168152602001610160565b600154610156565b61012e610985565b6008546001600160a01b0316610230565b61012e6109a4565b610156610b68565b61012e6102873660046119e7565b610bce565b61012e61029a3660046119e7565b610bd8565b610156610d5d565b61012e610d73565b600554610156565b6000811180156102d65750336000908152600660205260409020548111155b6102df57600080fd5b6102e76109a4565b80600060050160008282546102fc9190611afe565b90915550503360009081526006602052604081208054839290610320908490611afe565b90915550506004546103329082611b15565b3360009081526006602052604081206001018054909190610354908490611b34565b909155506000905061036582610e11565b6008549091506001600160a01b031663a9059cbb336103848486611afe565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af11580156103cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103f39190611b73565b506103fd81610e64565b604080518381526020810183905233917ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b568910160405180910390a25050565b6000811161044957600080fd5b6104516109a4565b6008546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa15801561049a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104be9190611b95565b6008546040516323b872dd60e01b8152336004820152306024820152604481018590529192506001600160a01b0316906323b872dd906064016020604051808303816000875af1158015610516573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061053a9190611b73565b506008546040516370a0823160e01b815230600482015260009183916001600160a01b03909116906370a0823190602401602060405180830381865afa158015610588573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ac9190611b95565b6105b69190611afe565b90506105c28482610ea8565b50505050565b6001600160a01b038116600090815260066020526040812060018101549054600454600160401b92916105fa91611b15565b6106049190611b34565b61060e9190611bc4565b92915050565b61061c6109a4565b6000610627336105c8565b905080156107115761063d600160401b82611b15565b336000908152600660205260408120600101805490919061065f908490611be6565b909155505060075460405163a9059cbb60e01b8152336004820152602481018390526001600160a01b039091169063a9059cbb906044016020604051808303816000875af11580156106b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106d99190611b73565b5060405181815233907f47cee97cb7acd717b3c0aa1435d004cd5b3c8c57d70dbceb4e4458bbd60e39d4906020015b60405180910390a25b50565b600080600080600080600080600080600061072e60015490565b9a50610738610d5d565b9950610742610b68565b985061075668056bc75e2d63100000610e11565b975061076160055490565b600254909750421161077457600061079f565b61079f610796610788600060020154610f9b565b61079142610f9b565b610ffb565b60005490611026565b6007546040516370a0823160e01b81526001600160a01b038f811660048301529298509116906370a0823190602401602060405180830381865afa1580156107eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061080f9190611b95565b6008546040516370a0823160e01b81526001600160a01b038f811660048301529297509116906370a0823190602401602060405180830381865afa15801561085b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061087f9190611b95565b600854604051636eb1769f60e11b81526001600160a01b038f8116600483015230602483015292965091169063dd62ed3e90604401602060405180830381865afa1580156108d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f59190611b95565b92506109168c6001600160a01b031660009081526006602052604090205490565b91506109218c6105c8565b905091939597999b90929496989a50565b600061093c611032565b801561095257506008546001600160a01b031633145b61095b57600080fd5b6000841161096857600080fd5b6109706109a4565b61097a8585610ea8565b506001949350505050565b33600090815260066020526040902054801561071157610711816102b7565b6002544290811180156109bf575060006109bd60055490565b115b156107115760006109e36107966109da600060020154610f9b565b61079185610f9b565b60035490915015610a03576003546109fb9082611c27565b600060035590505b6007546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015610a4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a709190611b95565b6007546040805163372500ab60e01b815290519293506001600160a01b039091169163372500ab9160048082019260009290919082900301818387803b158015610ab957600080fd5b505af1158015610acd573d6000803e3d6000fd5b50506007546040516370a0823160e01b81523060048201528493506001600160a01b0390911691506370a0823190602401602060405180830381865afa158015610b1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3f9190611b95565b610b499190611afe565b610b539083611c27565b60028490559150610b6382611070565b505050565b6000610b7360015490565b421015610baf57610baa610796610b91610b8c60015490565b610f9b565b610791610b9d60015490565b610b8c9062015180611c27565b905090565b610baa610796610bbe42610f9b565b610791610b8c4262015180611c27565b610711338261043c565b60008111610be557600080fd5b610bed6109a4565b6007546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015610c36573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5a9190611b95565b6007546040516323b872dd60e01b8152336004820152306024820152604481018590529192506001600160a01b0316906323b872dd906064016020604051808303816000875af1158015610cb2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cd69190611b73565b506007546040516370a0823160e01b815230600482015260009183916001600160a01b03909116906370a0823190602401602060405180830381865afa158015610d24573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d489190611b95565b610d529190611afe565b9050610b6381610e64565b6000610baa610796610d6e42610f9b565b6110d8565b610d7b611032565b610d8457600080fd5b610d8c6109a4565b6000610d97336105c8565b9050801561071157610dad600160401b82611b15565b3360009081526006602052604081206001018054909190610dcf908490611be6565b90915550610ddf90503382610ea8565b60405181815233907fbd654390d0d973e8c8376ed6053be8658870df892687852cc5c914d700291b8790602001610708565b6000610e1b611032565b610e2657600061060e565b61060e610e35610d6e42610f9b565b610e4790670de0b6b3a7640000611afe565b6064610e54600586611b15565b610e5e9190611bc4565b90611026565b801561071157600154421080610e7a5750600554155b15610e9f578060006003016000828254610e949190611c27565b909155506107119050565b61071181611070565b6000610eb382610e11565b90506000610ec18284611afe565b90508060006005016000828254610ed89190611c27565b90915550506001600160a01b03841660009081526006602052604081208054839290610f05908490611c27565b9091555050600454610f179082611b15565b6001600160a01b03851660009081526006602052604081206001018054909190610f42908490611be6565b90915550610f51905082610e64565b60408051848152602081018490526001600160a01b038616917f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a15910160405180910390a250505050565b600080610fa760015490565b905080831015610fba5750600092915050565b610ff4610fd262278d00670de0b6b3a7640000611b15565b610fdc8386611afe565b610fee90670de0b6b3a7640000611b15565b906110fc565b9392505050565b60008282101561100a57600080fd5b611013836110d8565b61101c836110d8565b610ff49190611afe565b6000610ff48383611111565b60006110466008546001600160a01b031690565b6001600160a01b03166110616007546001600160a01b031690565b6001600160a01b031614905090565b600554611081600160401b83611b15565b61108b9190611bc4565b6004805460009061109d908490611c27565b90915550506040518181527f3ac0594a85a20354f9dc74f33728416d19ce00d04a406c108cc2dcf2cecea1349060200160405180910390a150565b6000806110e4836111d8565b9050610ff481610fee670de0b6b3a764000082611afe565b6000610ff483670de0b6b3a76400008461121e565b60008080600019848609848602925082811083820303915050670de0b6b3a7640000811061115a5760405163698d9a0160e11b8152600481018290526024015b60405180910390fd5b600080670de0b6b3a76400008688099150506706f05b59d3b1ffff8111826111945780670de0b6b3a764000085040194505050505061060e565b620400008285030493909111909103600160ee1b02919091177faccb18165bd6fe31ae1cf318dc5b51eee0e1ba569b88cd74c1773b91fac106690201905092915050565b6000680a688906bd8b000000821061120657604051634a4f26f160e01b815260048101839052602401611151565b670de0b6b3a7640000604083901b04610ff4816112eb565b6000808060001985870985870292508281108382030391505080600014156112595783828161124f5761124f611bae565b0492505050610ff4565b83811061128357604051631dcf306360e21b81526004810182905260248101859052604401611151565b600084868809600260036001881981018916988990049182028318808302840302808302840302808302840302808302840302808302840302918202909203026000889003889004909101858311909403939093029303949094049190911702949350505050565b600160bf1b67800000000000000082161561130f5768016a09e667f3bcc9090260401c5b67400000000000000082161561132e576801306fe0a31b7152df0260401c5b67200000000000000082161561134d576801172b83c7d517adce0260401c5b67100000000000000082161561136c5768010b5586cf9890f62a0260401c5b67080000000000000082161561138b576801059b0d31585743ae0260401c5b6704000000000000008216156113aa57680102c9a3e778060ee70260401c5b6702000000000000008216156113c95768010163da9fb33356d80260401c5b6701000000000000008216156113e857680100b1afa5abcbed610260401c5b66800000000000008216156114065768010058c86da1c09ea20260401c5b6640000000000000821615611424576801002c605e2e8cec500260401c5b662000000000000082161561144257680100162f3904051fa10260401c5b6610000000000000821615611460576801000b175effdc76ba0260401c5b660800000000000082161561147e57680100058ba01fb9f96d0260401c5b660400000000000082161561149c5768010002c5cc37da94920260401c5b66020000000000008216156114ba576801000162e525ee05470260401c5b66010000000000008216156114d85768010000b17255775c040260401c5b658000000000008216156114f5576801000058b91b5bc9ae0260401c5b6540000000000082161561151257680100002c5c89d5ec6d0260401c5b6520000000000082161561152f5768010000162e43f4f8310260401c5b6510000000000082161561154c57680100000b1721bcfc9a0260401c5b650800000000008216156115695768010000058b90cf1e6e0260401c5b65040000000000821615611586576801000002c5c863b73f0260401c5b650200000000008216156115a357680100000162e430e5a20260401c5b650100000000008216156115c0576801000000b1721835510260401c5b6480000000008216156115dc57680100000058b90c0b490260401c5b6440000000008216156115f85768010000002c5c8601cc0260401c5b642000000000821615611614576801000000162e42fff00260401c5b6410000000008216156116305768010000000b17217fbb0260401c5b64080000000082161561164c576801000000058b90bfce0260401c5b64040000000082161561166857680100000002c5c85fe30260401c5b6402000000008216156116845768010000000162e42ff10260401c5b6401000000008216156116a057680100000000b17217f80260401c5b63800000008216156116bb5768010000000058b90bfc0260401c5b63400000008216156116d6576801000000002c5c85fe0260401c5b63200000008216156116f157680100000000162e42ff0260401c5b631000000082161561170c576801000000000b17217f0260401c5b630800000082161561172757680100000000058b90c00260401c5b63040000008216156117425768010000000002c5c8600260401c5b630200000082161561175d576801000000000162e4300260401c5b63010000008216156117785768010000000000b172180260401c5b62800000821615611792576801000000000058b90c0260401c5b624000008216156117ac57680100000000002c5c860260401c5b622000008216156117c65768010000000000162e430260401c5b621000008216156117e057680100000000000b17210260401c5b620800008216156117fa5768010000000000058b910260401c5b62040000821615611814576801000000000002c5c80260401c5b6202000082161561182e57680100000000000162e40260401c5b62010000821615611848576801000000000000b1720260401c5b61800082161561186157680100000000000058b90260401c5b61400082161561187a5768010000000000002c5d0260401c5b612000821615611893576801000000000000162e0260401c5b6110008216156118ac5768010000000000000b170260401c5b6108008216156118c5576801000000000000058c0260401c5b6104008216156118de57680100000000000002c60260401c5b6102008216156118f757680100000000000001630260401c5b61010082161561191057680100000000000000b10260401c5b608082161561192857680100000000000000590260401c5b6040821615611940576801000000000000002c0260401c5b602082161561195857680100000000000000160260401c5b6010821615611970576801000000000000000b0260401c5b600882161561198857680100000000000000060260401c5b60048216156119a057680100000000000000030260401c5b60028216156119b857680100000000000000010260401c5b60018216156119d057680100000000000000010260401c5b670de0b6b3a76400000260409190911c60bf031c90565b6000602082840312156119f957600080fd5b5035919050565b80356001600160a01b0381168114611a1757600080fd5b919050565b60008060408385031215611a2f57600080fd5b611a3883611a00565b946020939093013593505050565b600060208284031215611a5857600080fd5b610ff482611a00565b60008060008060608587031215611a7757600080fd5b611a8085611a00565b935060208501359250604085013567ffffffffffffffff80821115611aa457600080fd5b818701915087601f830112611ab857600080fd5b813581811115611ac757600080fd5b886020828501011115611ad957600080fd5b95989497505060200194505050565b634e487b7160e01b600052601160045260246000fd5b600082821015611b1057611b10611ae8565b500390565b6000816000190483118215151615611b2f57611b2f611ae8565b500290565b60008083128015600160ff1b850184121615611b5257611b52611ae8565b6001600160ff1b0384018313811615611b6d57611b6d611ae8565b50500390565b600060208284031215611b8557600080fd5b81518015158114610ff457600080fd5b600060208284031215611ba757600080fd5b5051919050565b634e487b7160e01b600052601260045260246000fd5b600082611be157634e487b7160e01b600052601260045260246000fd5b500490565b600080821280156001600160ff1b0384900385131615611c0857611c08611ae8565b600160ff1b8390038412811615611c2157611c21611ae8565b50500190565b60008219821115611c3a57611c3a611ae8565b50019056fea264697066735822122085ab3ecdd07e5de48258a7e7b79867e88425d9b2f19e550dd19f024e9e9d633964736f6c634300080b0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000000000000000000000108b2a2c280290940000000000000000000000000000000000000000000000000000000000000061e20e80000000000000000000000000a68dd8cb83097765263adad881af6eed479c4a33
-----Decoded View---------------
Arg [0] : _totalRewards (uint256): 20000000000000000000000000
Arg [1] : _stakingRewardsStart (uint256): 1642204800
Arg [2] : _token (address): 0xA68Dd8cB83097765263AdAD881Af6eeD479c4a33
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000000000000000000000108b2a2c28029094000000
Arg [1] : 0000000000000000000000000000000000000000000000000000000061e20e80
Arg [2] : 000000000000000000000000a68dd8cb83097765263adad881af6eed479c4a33
Deployed Bytecode Sourcemap
132:7221:4:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2894:445;;;;;;:::i;:::-;;:::i;:::-;;1855:344;;;;;;:::i;:::-;;:::i;4367:191::-;;;;;;:::i;:::-;;:::i;:::-;;;973:25:8;;;961:2;946:18;4367:191:4;;;;;;;;3342:266;;;:::i;5001:895::-;;;;;;:::i;:::-;;:::i;:::-;;;;1437:25:8;;;1493:2;1478:18;;1471:34;;;;1521:18;;;1514:34;;;;1579:2;1564:18;;1557:34;;;;1622:3;1607:19;;1600:35;;;;1666:3;1651:19;;1644:35;;;;1710:3;1695:19;;1688:35;1754:3;1739:19;;1732:35;1798:3;1783:19;;1776:35;1842:3;1827:19;;1820:35;1886:3;1871:19;;1864:36;1424:3;1409:19;5001:895:4;1009:897:8;4255:108:4;;;;;;:::i;:::-;-1:-1:-1;;;;;4332:17:4;4312:7;4332:17;;;:10;:17;;;;;:27;;4255:108;2202:231;;;;;;:::i;:::-;;:::i;:::-;;;2814:14:8;;2807:22;2789:41;;2777:2;2762:18;2202:231:4;2649:187:8;3900:84:4;3971:8;;-1:-1:-1;;;;;3971:8:4;3900:84;;;-1:-1:-1;;;;;3005:32:8;;;2987:51;;2975:2;2960:18;3900:84:4;2841:203:8;4079:80:4;4141:14;;4079:80;;2756:135;;;:::i;3988:88::-;4061:10;;-1:-1:-1;;;;;4061:10:4;3988:88;;1253:514;;;:::i;4562:309::-;;;:::i;1770:82::-;;;;;;:::i;:::-;;:::i;2436:317::-;;;;;;:::i;:::-;;:::i;4874:124::-;;;:::i;3611:284::-;;;:::i;4162:90::-;4229:19;;4162:90;;2894:445;2958:1;2948:7;:11;:49;;;;-1:-1:-1;2986:10:4;4312:7;4332:17;;;:10;:17;;;;;:27;2963:7;:34;;2948:49;2940:58;;;;;;3002:8;:6;:8::i;:::-;3037:7;3014:4;:19;;;:30;;;;;;;:::i;:::-;;;;-1:-1:-1;;3059:10:4;3048:4;:22;;;:10;:22;;;;;:43;;3084:7;;3048:4;:43;;3084:7;;3048:43;:::i;:::-;;;;-1:-1:-1;;3151:26:4;;3141:36;;:7;:36;:::i;:::-;3106:10;3095:4;:22;;;:10;:22;;;;;:35;;:83;;:35;;:4;:83;;;;;:::i;:::-;;;;-1:-1:-1;3182:12:4;;-1:-1:-1;3197:22:4;3211:7;3197:13;:22::i;:::-;3223:10;;3182:37;;-1:-1:-1;;;;;;3223:10:4;:19;3243:10;3255:14;3182:37;3255:7;:14;:::i;:::-;3223:47;;-1:-1:-1;;;;;;3223:47:4;;;;;;;-1:-1:-1;;;;;3948:32:8;;;3223:47:4;;;3930:51:8;3997:18;;;3990:34;3903:18;;3223:47:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;3274:17;3286:4;3274:11;:17::i;:::-;3300:35;;;4491:25:8;;;4547:2;4532:18;;4525:34;;;3309:10:4;;3300:35;;4464:18:8;3300:35:4;;;;;;;2936:403;2894:445;:::o;1855:344::-;1936:1;1926:7;:11;1918:20;;;;;;1942:8;:6;:8::i;:::-;1979:10;;:35;;-1:-1:-1;;;1979:35:4;;2008:4;1979:35;;;2987:51:8;1954:22:4;;-1:-1:-1;;;;;1979:10:4;;:20;;2960:18:8;;1979:35:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2018:10;;:59;;-1:-1:-1;;;2018:59:4;;2042:10;2018:59;;;4999:34:8;2062:4:4;5049:18:8;;;5042:43;5101:18;;;5094:34;;;1954:60:4;;-1:-1:-1;;;;;;2018:10:4;;:23;;4934:18:8;;2018:59:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;2107:10:4;;:35;;-1:-1:-1;;;2107:35:4;;2136:4;2107:35;;;2987:51:8;2081:23:4;;2145:14;;-1:-1:-1;;;;;2107:10:4;;;;:20;;2960:18:8;;2107:35:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:52;;;;:::i;:::-;2081:78;;2163:32;2172:5;2179:15;2163:8;:32::i;:::-;1914:285;;1855:344;;:::o;4367:191::-;-1:-1:-1;;;;;4508:17:4;;4422:7;4508:17;;;:10;:17;;;;;:30;;;;4332:27;;4457:26;;-1:-1:-1;;;236:5:4;4508:30;4457:47;;;:::i;:::-;4450:88;;;;:::i;:::-;4442:112;;;;:::i;:::-;4435:119;4367:191;-1:-1:-1;;4367:191:4:o;3342:266::-;3370:8;:6;:8::i;:::-;3382:16;3401:21;3411:10;3401:9;:21::i;:::-;3382:40;-1:-1:-1;3430:12:4;;3426:179;;3495:23;-1:-1:-1;;;3495:8:4;:23;:::i;:::-;3460:10;3449:4;:22;;;:10;:22;;;;;:35;;:70;;:35;;:4;:70;;;;;:::i;:::-;;;;-1:-1:-1;;3524:8:4;;:39;;-1:-1:-1;;;3524:39:4;;3542:10;3524:39;;;3930:51:8;3997:18;;;3990:34;;;-1:-1:-1;;;;;3524:8:4;;;;:17;;3903:18:8;;3524:39:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;3573:27:4;;973:25:8;;;3579:10:4;;3573:27;;961:2:8;946:18;3573:27:4;;;;;;;;3426:179;3366:242;3342:266::o;5001:895::-;5059:20;5081:31;5114:25;5141;5168:28;5198:22;5222:15;5239:19;5260:21;5283;5306:19;5346:11;4141:14;;;4079:80;5346:11;5331:26;;5387:18;:16;:18::i;:::-;5361:44;;5429:19;:17;:19::i;:::-;5409:39;;5472:19;5486:4;5472:13;:19::i;:::-;5452:39;;5518:16;4229:19;;;4162:90;5518:16;5573;;5495:39;;-1:-1:-1;5555:15:4;:34;:119;;5673:1;5555:119;;;5592:78;5614:55;5621:23;5627:4;:16;;;5621:5;:23::i;:::-;5646:22;5652:15;5646:5;:22::i;:::-;5614:6;:55::i;:::-;5592:4;:17;;:21;:78::i;:::-;5688:8;;:25;;-1:-1:-1;;;5688:25:4;;-1:-1:-1;;;;;3005:32:8;;;5688:25:4;;;2987:51:8;5538:136:4;;-1:-1:-1;5688:8:4;;;:18;;2960::8;;5688:25:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5731:10;;:27;;-1:-1:-1;;;5731:27:4;;-1:-1:-1;;;;;3005:32:8;;;5731:27:4;;;2987:51:8;5678:35:4;;-1:-1:-1;5731:10:4;;;:20;;2960:18:8;;5731:27:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5778:10;;:42;;-1:-1:-1;;;5778:42:4;;-1:-1:-1;;;;;5993:15:8;;;5778:42:4;;;5975:34:8;5814:4:4;6025:18:8;;;6018:43;5717:41:4;;-1:-1:-1;5778:10:4;;;:20;;5910:18:8;;5778:42:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5762:58;;5840:18;5852:5;-1:-1:-1;;;;;4332:17:4;4312:7;4332:17;;;:10;:17;;;;;:27;;4255:108;5840:18;5824:34;;5876:16;5886:5;5876:9;:16::i;:::-;5862:30;;5001:895;;;;;;;;;;;;;:::o;2202:231::-;2291:4;2309:8;:6;:8::i;:::-;:40;;;;-1:-1:-1;4061:10:4;;-1:-1:-1;;;;;4061:10:4;2321;:28;2309:40;2301:49;;;;;;2372:1;2362:7;:11;2354:20;;;;;;2378:8;:6;:8::i;:::-;2390:24;2399:5;2406:7;2390:8;:24::i;:::-;-1:-1:-1;2425:4:4;2202:231;;;;;;:::o;2756:135::-;2823:10;2790:18;4332:17;;;:10;:17;;;;;:27;2842:14;;2838:50;;2863:20;2872:10;2863:8;:20::i;1253:514::-;1327:16;;1297:15;;1320:23;;:47;;;;;1366:1;1347:16;4229:19;;;4162:90;1347:16;:20;1320:47;1316:448;;;1374:15;1392:67;1414:44;1421:23;1427:4;:16;;;1421:5;:23::i;:::-;1446:11;1452:4;1446:5;:11::i;1392:67::-;1468:15;;1374:85;;-1:-1:-1;1468:19:4;1464:88;;1506:15;;1495:26;;;;:::i;:::-;1545:1;1527:15;:19;1495:26;-1:-1:-1;1464:88:4;1581:8;;:33;;-1:-1:-1;;;1581:33:4;;1608:4;1581:33;;;2987:51:8;1556:22:4;;-1:-1:-1;;;;;1581:8:4;;:18;;2960::8;;1581:33:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1619:8;;:23;;;-1:-1:-1;;;1619:23:4;;;;1556:58;;-1:-1:-1;;;;;;1619:8:4;;;;:21;;:23;;;;;:4;;:23;;;;;;;;:4;:8;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1658:8:4;;:33;;-1:-1:-1;;;1658:33:4;;1685:4;1658:33;;;2987:51:8;1694:14:4;;-1:-1:-1;;;;;;1658:8:4;;;;-1:-1:-1;1658:18:4;;2960::8;;1658:33:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:50;;;;:::i;:::-;1647:61;;;;:::i;:::-;1713:16;:23;;;1647:61;-1:-1:-1;1741:18:4;1647:61;1741:9;:18::i;:::-;1369:395;;1278:489;1253:514::o;4562:309::-;4612:7;4647:11;4141:14;;;4079:80;4647:11;4629:15;:29;4625:243;;;4672:80;4694:57;4701:18;4707:11;4141:14;;;4079:80;4707:11;4701:5;:18::i;:::-;4721:29;4727:11;4141:14;;;4079:80;4727:11;:22;;4741:8;4727:22;:::i;4672:80::-;4665:87;;4562:309;:::o;4625:243::-;4775:88;4797:65;4804:22;4810:15;4804:5;:22::i;:::-;4828:33;4834:26;:15;4852:8;4834:26;:::i;1770:82::-;1817:31;1828:10;1840:7;1817:10;:31::i;2436:317::-;2500:1;2490:7;:11;2482:20;;;;;;2506:8;:6;:8::i;:::-;2543;;:33;;-1:-1:-1;;;2543:33:4;;2570:4;2543:33;;;2987:51:8;2518:22:4;;-1:-1:-1;;;;;2543:8:4;;:18;;2960::8;;2543:33:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2580:8;;:57;;-1:-1:-1;;;2580:57:4;;2602:10;2580:57;;;4999:34:8;2622:4:4;5049:18:8;;;5042:43;5101:18;;;5094:34;;;2518:58:4;;-1:-1:-1;;;;;;2580:8:4;;:21;;4934:18:8;;2580:57:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;2667:8:4;;:33;;-1:-1:-1;;;2667:33:4;;2694:4;2667:33;;;2987:51:8;2641:23:4;;2703:14;;-1:-1:-1;;;;;2667:8:4;;;;:18;;2960::8;;2667:33:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:50;;;;:::i;:::-;2641:76;;2721:28;2733:15;2721:11;:28::i;4874:124::-;4923:7;4943:51;4965:28;4970:22;4976:15;4970:5;:22::i;:::-;4965:4;:28::i;3611:284::-;3650:8;:6;:8::i;:::-;3642:17;;;;;;3663:8;:6;:8::i;:::-;3675:16;3694:21;3704:10;3694:9;:21::i;:::-;3675:40;-1:-1:-1;3723:12:4;;3719:173;;3788:23;-1:-1:-1;;;3788:8:4;:23;:::i;:::-;3753:10;3742:4;:22;;;:10;:22;;;;;:35;;:70;;:35;;:4;:70;;;;;:::i;:::-;;;;-1:-1:-1;3817:30:4;;-1:-1:-1;3826:10:4;3838:8;3817;:30::i;:::-;3857;;973:25:8;;;3866:10:4;;3857:30;;961:2:8;946:18;3857:30:4;827:177:8;6726:172:4;6789:7;6809:8;:6;:8::i;:::-;:85;;6893:1;6809:85;;;6820:70;6861:28;6866:22;6872:15;6866:5;:22::i;6861:28::-;6854:35;;:4;:35;:::i;:::-;6845:3;6821:21;283:1;6821:7;:21;:::i;:::-;:27;;;;:::i;:::-;6820:33;;:70::i;6274:202::-;6326:8;;6322:151;;4141:14;;6345:15;:29;:54;;;-1:-1:-1;4229:19:4;;6378:21;6345:54;6341:128;;;6426:4;6407;:15;;;:23;;;;;;;:::i;:::-;;;;-1:-1:-1;6341:128:4;;-1:-1:-1;6341:128:4;;6448:15;6458:4;6448:9;:15::i;5901:369::-;5964:12;5979:22;5993:7;5979:13;:22::i;:::-;5964:37;-1:-1:-1;6005:18:4;6026:14;5964:37;6026:7;:14;:::i;:::-;6005:35;;6067:10;6044:4;:19;;;:33;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;6081:17:4;;:4;:17;;;:10;:17;;;;;:41;;6112:10;;6081:4;:41;;6112:10;;6081:41;:::i;:::-;;;;-1:-1:-1;;6180:26:4;;6167:39;;:10;:39;:::i;:::-;-1:-1:-1;;;;;6126:17:4;;:4;:17;;;:10;:17;;;;;:30;;:81;;:30;;:4;:81;;;;;:::i;:::-;;;;-1:-1:-1;6211:17:4;;-1:-1:-1;6223:4:4;6211:11;:17::i;:::-;6237:29;;;4491:25:8;;;4547:2;4532:18;;4525:34;;;-1:-1:-1;;;;;6237:29:4;;;;;4464:18:8;6237:29:4;;;;;;;5960:310;;5901:369;;:::o;6902:194::-;6951:7;6964:14;6981:11;4141:14;;;4079:80;6981:11;6964:28;;7004:6;7000:1;:10;6996:97;;;-1:-1:-1;7024:1:4;;6902:194;-1:-1:-1;;6902:194:4:o;6996:97::-;7048:40;7074:13;345:7;7083:4;7074:13;:::i;:::-;7050:10;7054:6;7050:1;:10;:::i;:::-;7049:19;;7064:4;7049:19;:::i;:::-;7048:25;;:40::i;:::-;7041:47;6902:194;-1:-1:-1;;;6902:194:4:o;7224:127::-;7287:7;7314:2;7308;:8;;7300:17;;;;;;7339:8;7344:2;7339:4;:8::i;:::-;7328;7333:2;7328:4;:8::i;:::-;:19;;;;:::i;19080:121:3:-;19138:14;19167:30;19192:1;19195;19167:24;:30::i;6631:92:4:-;6672:4;6705:14;4061:10;;-1:-1:-1;;;;;4061:10:4;;3988:88;6705:14;-1:-1:-1;;;;;6689:30:4;:12;3971:8;;-1:-1:-1;;;;;3971:8:4;;3900:84;6689:12;-1:-1:-1;;;;;6689:30:4;;6682:37;;6631:92;:::o;6479:148::-;4229:19;;6558:22;-1:-1:-1;;;6558:7:4;:22;:::i;:::-;:41;;;;:::i;:::-;6528:26;:71;;:4;;:71;;;;;:::i;:::-;;;;-1:-1:-1;;6608:15:4;;973:25:8;;;6608:15:4;;961:2:8;946:18;6608:15:4;;;;;;;6479:148;:::o;7099:122::-;7147:7;7160:12;7175:8;:1;:6;:8::i;:::-;7160:23;-1:-1:-1;7194:23:4;7160;7195:11;7202:4;7160:23;7195:11;:::i;3578:118:3:-;3636:14;3665:27;3680:1;1317:4;3690:1;3665:14;:27::i;17116:831:2:-;17187:14;;;-1:-1:-1;;17275:1:2;17272;17265:20;17305:1;17302;17298:9;17289:18;;17347:5;17343:2;17340:13;17332:5;17328:2;17324:14;17320:34;17311:43;;;4174:4;17366:5;:14;17362:77;;17394:40;;-1:-1:-1;;;17394:40:2;;;;;973:25:8;;;946:18;;17394:40:2;;;;;;;;17362:77;17443:17;17464:19;17527:5;17524:1;17521;17514:19;17501:32;-1:-1:-1;;17566:18:2;17552:33;;17597:10;17593:104;;17657:11;4174:4;17640:5;:13;17639:29;17630:38;;17674:13;;;;;;17593:104;17868:11;17758:21;;;17754:39;17816:20;;;;17805:32;;;-1:-1:-1;;;17801:84:2;17744:148;;;;17899:13;17734:184;17725:215;;-1:-1:-1;17116:831:2;;;;:::o;5154:478:3:-;5202:14;5317:6;5312:1;:11;5308:68;;5337:34;;-1:-1:-1;;;5337:34:3;;;;;973:25:8;;;946:18;;5337:34:3;827:177:8;5308:68:3;1317:4;5473:2;5468:7;;;5467:17;5603:21;5467:17;5603:12;:21::i;12637:3407:2:-;12728:14;;;-1:-1:-1;;13172:1:2;13169;13162:20;13202:1;13199;13195:9;13186:18;;13244:5;13240:2;13237:13;13229:5;13225:2;13221:14;13217:34;13208:43;;;13316:5;13325:1;13316:10;13312:93;;;13366:11;13358:5;:19;;;;;:::i;:::-;;13349:28;;13387:13;;;;13312:93;13500:11;13491:5;:20;13487:86;;13525:43;;-1:-1:-1;;;13525:43:2;;;;;4491:25:8;;;4532:18;;;4525:34;;;4464:18;;13525:43:2;4317:248:8;13487:86:2;13778:17;13877:11;13874:1;13871;13864:25;15073:1;15054;14354;14339:12;;:16;;14324:32;;14429:25;;;;15054:15;;;15053:21;;15279;;;15275:25;;15264:36;15339:21;;;15335:25;;15324:36;15400:21;;;15396:25;;15385:36;15461:21;;;15457:25;;15446:36;15522:21;;;15518:25;;15507:36;15584:21;;;15580:25;;;15569:36;14306:15;14647;;;14643:29;;;14639:37;;;13965:20;;;13954:32;;;14738:15;;;;13999:21;;14509:19;;;;14729:24;;;;16003:15;;12637:3407;-1:-1:-1;;;;12637:3407:2:o;4811:6413::-;-1:-1:-1;;;5229:18:2;5225:22;;:26;5221:89;;5278:19;5269:28;5302:2;5268:36;5221:89;5322:18;5318:22;;:26;5314:89;;5371:19;5362:28;5395:2;5361:36;5314:89;5415:18;5411:22;;:26;5407:89;;5464:19;5455:28;5488:2;5454:36;5407:89;5508:18;5504:22;;:26;5500:89;;5557:19;5548:28;5581:2;5547:36;5500:89;5601:17;5597:21;;:25;5593:88;;5649:19;5640:28;5673:2;5639:36;5593:88;5693:17;5689:21;;:25;5685:88;;5741:19;5732:28;5765:2;5731:36;5685:88;5785:17;5781:21;;:25;5777:88;;5833:19;5824:28;5857:2;5823:36;5777:88;5877:17;5873:21;;:25;5869:88;;5925:19;5916:28;5949:2;5915:36;5869:88;5969:16;5965:20;;:24;5961:87;;6016:19;6007:28;6040:2;6006:36;5961:87;6060:16;6056:20;;:24;6052:87;;6107:19;6098:28;6131:2;6097:36;6052:87;6151:16;6147:20;;:24;6143:87;;6198:19;6189:28;6222:2;6188:36;6143:87;6242:16;6238:20;;:24;6234:87;;6289:19;6280:28;6313:2;6279:36;6234:87;6333:15;6329:19;;:23;6325:86;;6379:19;6370:28;6403:2;6369:36;6325:86;6423:15;6419:19;;:23;6415:86;;6469:19;6460:28;6493:2;6459:36;6415:86;6513:15;6509:19;;:23;6505:86;;6559:19;6550:28;6583:2;6549:36;6505:86;6603:15;6599:19;;:23;6595:86;;6649:19;6640:28;6673:2;6639:36;6595:86;6693:14;6689:18;;:22;6685:85;;6738:19;6729:28;6762:2;6728:36;6685:85;6782:14;6778:18;;:22;6774:85;;6827:19;6818:28;6851:2;6817:36;6774:85;6871:14;6867:18;;:22;6863:85;;6916:19;6907:28;6940:2;6906:36;6863:85;6960:14;6956:18;;:22;6952:85;;7005:19;6996:28;7029:2;6995:36;6952:85;7049:13;7045:17;;:21;7041:84;;7093:19;7084:28;7117:2;7083:36;7041:84;7137:13;7133:17;;:21;7129:84;;7181:19;7172:28;7205:2;7171:36;7129:84;7225:13;7221:17;;:21;7217:84;;7269:19;7260:28;7293:2;7259:36;7217:84;7313:13;7309:17;;:21;7305:84;;7357:19;7348:28;7381:2;7347:36;7305:84;7401:12;7397:16;;:20;7393:83;;7444:19;7435:28;7468:2;7434:36;7393:83;7488:12;7484:16;;:20;7480:83;;7531:19;7522:28;7555:2;7521:36;7480:83;7575:12;7571:16;;:20;7567:83;;7618:19;7609:28;7642:2;7608:36;7567:83;7662:12;7658:16;;:20;7654:83;;7705:19;7696:28;7729:2;7695:36;7654:83;7749:11;7745:15;;:19;7741:82;;7791:19;7782:28;7815:2;7781:36;7741:82;7835:11;7831:15;;:19;7827:82;;7877:19;7868:28;7901:2;7867:36;7827:82;7921:11;7917:15;;:19;7913:82;;7963:19;7954:28;7987:2;7953:36;7913:82;8007:11;8003:15;;:19;7999:82;;8049:19;8040:28;8073:2;8039:36;7999:82;8093:10;8089:14;;:18;8085:81;;8134:19;8125:28;8158:2;8124:36;8085:81;8178:10;8174:14;;:18;8170:81;;8219:19;8210:28;8243:2;8209:36;8170:81;8263:10;8259:14;;:18;8255:81;;8304:19;8295:28;8328:2;8294:36;8255:81;8348:10;8344:14;;:18;8340:81;;8389:19;8380:28;8413:2;8379:36;8340:81;8433:9;8429:13;;:17;8425:80;;8473:19;8464:28;8497:2;8463:36;8425:80;8517:9;8513:13;;:17;8509:80;;8557:19;8548:28;8581:2;8547:36;8509:80;8601:9;8597:13;;:17;8593:80;;8641:19;8632:28;8665:2;8631:36;8593:80;8685:9;8681:13;;:17;8677:80;;8725:19;8716:28;8749:2;8715:36;8677:80;8769:8;8765:12;;:16;8761:79;;8808:19;8799:28;8832:2;8798:36;8761:79;8852:8;8848:12;;:16;8844:79;;8891:19;8882:28;8915:2;8881:36;8844:79;8935:8;8931:12;;:16;8927:79;;8974:19;8965:28;8998:2;8964:36;8927:79;9018:8;9014:12;;:16;9010:79;;9057:19;9048:28;9081:2;9047:36;9010:79;9101:7;9097:11;;:15;9093:78;;9139:19;9130:28;9163:2;9129:36;9093:78;9183:7;9179:11;;:15;9175:78;;9221:19;9212:28;9245:2;9211:36;9175:78;9265:7;9261:11;;:15;9257:78;;9303:19;9294:28;9327:2;9293:36;9257:78;9347:7;9343:11;;:15;9339:78;;9385:19;9376:28;9409:2;9375:36;9339:78;9429:6;9425:10;;:14;9421:77;;9466:19;9457:28;9490:2;9456:36;9421:77;9510:6;9506:10;;:14;9502:77;;9547:19;9538:28;9571:2;9537:36;9502:77;9591:6;9587:10;;:14;9583:77;;9628:19;9619:28;9652:2;9618:36;9583:77;9672:6;9668:10;;:14;9664:77;;9709:19;9700:28;9733:2;9699:36;9664:77;9753:5;9749:9;;:13;9745:76;;9789:19;9780:28;9813:2;9779:36;9745:76;9833:5;9829:9;;:13;9825:76;;9869:19;9860:28;9893:2;9859:36;9825:76;9913:5;9909:9;;:13;9905:76;;9949:19;9940:28;9973:2;9939:36;9905:76;9993:5;9989:9;;:13;9985:76;;10029:19;10020:28;10053:2;10019:36;9985:76;10073:4;10069:8;;:12;10065:75;;10108:19;10099:28;10132:2;10098:36;10065:75;10152:4;10148:8;;:12;10144:75;;10187:19;10178:28;10211:2;10177:36;10144:75;10231:4;10227:8;;:12;10223:75;;10266:19;10257:28;10290:2;10256:36;10223:75;10310:4;10306:8;;:12;10302:75;;10345:19;10336:28;10369:2;10335:36;10302:75;10389:3;10385:7;;:11;10381:74;;10423:19;10414:28;10447:2;10413:36;10381:74;10467:3;10463:7;;:11;10459:74;;10501:19;10492:28;10525:2;10491:36;10459:74;10545:3;10541:7;;:11;10537:74;;10579:19;10570:28;10603:2;10569:36;10537:74;10623:3;10619:7;;:11;10615:74;;10657:19;10648:28;10681:2;10647:36;10615:74;4174:4;11168:15;11212:2;11207:7;;;;11200:3;:15;11188:28;;4811:6413::o;14:180:8:-;73:6;126:2;114:9;105:7;101:23;97:32;94:52;;;142:1;139;132:12;94:52;-1:-1:-1;165:23:8;;14:180;-1:-1:-1;14:180:8:o;199:173::-;267:20;;-1:-1:-1;;;;;316:31:8;;306:42;;296:70;;362:1;359;352:12;296:70;199:173;;;:::o;377:254::-;445:6;453;506:2;494:9;485:7;481:23;477:32;474:52;;;522:1;519;512:12;474:52;545:29;564:9;545:29;:::i;:::-;535:39;621:2;606:18;;;;593:32;;-1:-1:-1;;;377:254:8:o;636:186::-;695:6;748:2;736:9;727:7;723:23;719:32;716:52;;;764:1;761;754:12;716:52;787:29;806:9;787:29;:::i;1911:733::-;1999:6;2007;2015;2023;2076:2;2064:9;2055:7;2051:23;2047:32;2044:52;;;2092:1;2089;2082:12;2044:52;2115:29;2134:9;2115:29;:::i;:::-;2105:39;;2191:2;2180:9;2176:18;2163:32;2153:42;;2246:2;2235:9;2231:18;2218:32;2269:18;2310:2;2302:6;2299:14;2296:34;;;2326:1;2323;2316:12;2296:34;2364:6;2353:9;2349:22;2339:32;;2409:7;2402:4;2398:2;2394:13;2390:27;2380:55;;2431:1;2428;2421:12;2380:55;2471:2;2458:16;2497:2;2489:6;2486:14;2483:34;;;2513:1;2510;2503:12;2483:34;2558:7;2553:2;2544:6;2540:2;2536:15;2532:24;2529:37;2526:57;;;2579:1;2576;2569:12;2526:57;1911:733;;;;-1:-1:-1;;2610:2:8;2602:11;;-1:-1:-1;;;1911:733:8:o;3049:127::-;3110:10;3105:3;3101:20;3098:1;3091:31;3141:4;3138:1;3131:15;3165:4;3162:1;3155:15;3181:125;3221:4;3249:1;3246;3243:8;3240:34;;;3254:18;;:::i;:::-;-1:-1:-1;3291:9:8;;3181:125::o;3311:168::-;3351:7;3417:1;3413;3409:6;3405:14;3402:1;3399:21;3394:1;3387:9;3380:17;3376:45;3373:71;;;3424:18;;:::i;:::-;-1:-1:-1;3464:9:8;;3311:168::o;3484:267::-;3523:4;3552:9;;;3577:10;;-1:-1:-1;;;3596:19:8;;3589:27;;3573:44;3570:70;;;3620:18;;:::i;:::-;-1:-1:-1;;;;;3667:27:8;;3660:35;;3652:44;;3649:70;;;3699:18;;:::i;:::-;-1:-1:-1;;3736:9:8;;3484:267::o;4035:277::-;4102:6;4155:2;4143:9;4134:7;4130:23;4126:32;4123:52;;;4171:1;4168;4161:12;4123:52;4203:9;4197:16;4256:5;4249:13;4242:21;4235:5;4232:32;4222:60;;4278:1;4275;4268:12;4570:184;4640:6;4693:2;4681:9;4672:7;4668:23;4664:32;4661:52;;;4709:1;4706;4699:12;4661:52;-1:-1:-1;4732:16:8;;4570:184;-1:-1:-1;4570:184:8:o;5139:127::-;5200:10;5195:3;5191:20;5188:1;5181:31;5231:4;5228:1;5221:15;5255:4;5252:1;5245:15;5271:217;5311:1;5337;5327:132;;5381:10;5376:3;5372:20;5369:1;5362:31;5416:4;5413:1;5406:15;5444:4;5441:1;5434:15;5327:132;-1:-1:-1;5473:9:8;;5271:217::o;5493:265::-;5532:3;5560:9;;;5585:10;;-1:-1:-1;;;;;5604:27:8;;;5597:35;;5581:52;5578:78;;;5636:18;;:::i;:::-;-1:-1:-1;;;5683:19:8;;;5676:27;;5668:36;;5665:62;;;5707:18;;:::i;:::-;-1:-1:-1;;5743:9:8;;5493:265::o;6072:128::-;6112:3;6143:1;6139:6;6136:1;6133:13;6130:39;;;6149:18;;:::i;:::-;-1:-1:-1;6185:9:8;;6072:128::o
Swarm Source
ipfs://85ab3ecdd07e5de48258a7e7b79867e88425d9b2f19e550dd19f024e9e9d6339
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.