Token SH33P Staking
Overview CRC20
Price
$0.00 @ 0.000000 CRO
Fully Diluted Market Cap
Total Supply:
243,104.140804 xSH33P
Holders:
645 addresses
Contract:
Decimals:
18
Balance
7.515772909831758303 xSH33PValue
$0.00
[ Download CSV Export ]
[ Download CSV Export ]
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
StakingToken
Compiler Version
v0.7.4+commit.3f05b770
Contract Source Code (Solidity Multiple files format)
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity ^0.7.4; import "./SafeMath.sol"; import "./IERC20.sol"; import "./ERC20.sol"; import "./TokensRecoverable.sol"; contract StakingToken is ERC20("SH33P Staking", "xSH33P"), TokensRecoverable { using SafeMath for uint256; IERC20 public immutable rooted; uint256 public totalStakers; uint256 public allTimeStaked; uint256 public allTimeUnstaked; struct AddressRecords { uint256 totalStaked; uint256 totalUnstaked; } mapping(address => AddressRecords) public addressRecord; event onStakeTokens(address indexed _caller, uint256 _amount, uint256 _timestamp); event onUnstakeTokens(address indexed _caller, uint256 _amount, uint256 _timestamp); constructor(IERC20 _rooted) { rooted = _rooted; } function statsOf(address _user) public view returns (uint256 _totalStaked, uint256 _totalUnstaked) { return ( addressRecord[_user].totalStaked, addressRecord[_user].totalUnstaked ); } function baseToStaked(uint256 _amount) public view returns (uint256 _stakedAmount) { uint256 totalRooted = rooted.balanceOf(address(this)); uint256 totalShares = this.totalSupply(); if (totalShares == 0 || totalRooted == 0) { return _amount; } else { return _amount.mul(totalShares).div(totalRooted); } } function stakedToBase(uint256 _amount) public view returns (uint256 _baseAmount) { uint256 totalShares = this.totalSupply(); return _amount.mul(rooted.balanceOf(address(this))).div(totalShares); } // Stake rooted, get staking shares function stake(uint256 amount) public { uint256 totalRooted = rooted.balanceOf(address(this)); uint256 totalShares = this.totalSupply(); if (addressRecord[msg.sender].totalStaked == 0) { totalStakers += 1; } if (totalShares == 0 || totalRooted == 0) { _mint(msg.sender, amount); } else { uint256 mintAmount = amount.mul(totalShares).div(totalRooted); _mint(msg.sender, mintAmount); } rooted.transferFrom(msg.sender, address(this), amount); addressRecord[msg.sender].totalStaked += amount; allTimeStaked += amount; emit onStakeTokens(msg.sender, amount, block.timestamp); } // Unstake shares, claim back rooted function unstake(uint256 share) public { uint256 totalShares = this.totalSupply(); uint256 unstakeAmount = share.mul(rooted.balanceOf(address(this))).div(totalShares); _burn(msg.sender, share); rooted.transfer(msg.sender, unstakeAmount); addressRecord[msg.sender].totalUnstaked += unstakeAmount; allTimeUnstaked += unstakeAmount; emit onUnstakeTokens(msg.sender, share, block.timestamp); } function canRecoverTokens(IERC20 token) internal override view returns (bool) { return address(token) != address(this) && address(token) != address(rooted); } }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity ^0.7.4; library Address { function isContract(address account) internal view returns (bool) { uint256 size; assembly { size := extcodesize(account) } return size > 0; } function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{ value: value }(data); return _verifyCallResult(success, returndata, errorMessage); } function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { if (success) { return returndata; } else { if (returndata.length > 0) { assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity ^0.7.4; // The burn pit is a step above a simple burn address // It will serve the community by collecting a redistributing fees // Oscillating between 50-51% import "./Address.sol"; import "./SafeMath.sol"; import "./SafeERC20.sol"; import "./IERC20.sol"; import "./Whitelist.sol"; contract BurnPit is Whitelist { using Address for address; using SafeMath for uint256; using SafeERC20 for IERC20; IERC20 public token; uint256 internal _divisor; uint256 internal _lastRebalance; uint256 internal _lowerboundPercentage; uint256 internal _upperboundPercentage; event Rebalance(uint256 tokens); modifier ifReady() { require(isReady(), "NOT_READY_YET"); _; } constructor (address _mainUser, address _token, uint _oneHundredPercent) { _divisor = _oneHundredPercent; //get a handle on the token token = IERC20(_token); // a rebalance isn't necessary at launch _lastRebalance = block.timestamp; addAddressToWhitelist(msg.sender); addAddressToWhitelist(_mainUser); } function isReady() public view returns (bool) { (uint256 _upper, ) = percentages(); uint256 _total = tokenBalance(); if (_total > _upper){ return true; } return false; } // WRITE FUNCTIONS // function percentages() public view returns (uint256, uint256) { return (_upperboundPercentage, _lowerboundPercentage); } function limits() public view returns (uint256, uint256) { return ( (token.totalSupply().mul(_upperboundPercentage).div(_divisor)), (token.totalSupply().mul(_lowerboundPercentage).div(_divisor)) ); } function tokenBalance() public view returns (uint256) { return (token.balanceOf(address(this))); } function pendingReward() public view returns (uint256) { (, uint256 _lower) = percentages(); uint256 total = tokenBalance(); return (total.sub(_lower)); } function rebalance() external onlyWhitelisted() ifReady() returns (bool _success){ uint256 boost = pendingReward(); token.transfer(address(token), boost); _lastRebalance = block.timestamp; emit Rebalance(boost); return true; } }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity ^0.7.4; abstract contract Context { function _msgSender() internal view virtual returns (address payable) { return msg.sender; } function _msgData() internal view virtual returns (bytes memory) { this; return msg.data; } }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity ^0.7.4; import "./SafeMath.sol"; /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented or decremented by one. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids. * * Include with `using Counters for Counters.Counter;` * Since it is not possible to overflow a 256 bit integer with increments of one, `increment` can skip the {SafeMath} * overflow check, thereby saving gas. This does assume however correct usage, in that the underlying `_value` is never * directly accessed. */ library Counters { using SafeMath for uint256; struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { // The {SafeMath} overflow check can be skipped here, see the comment at the top counter._value += 1; } function decrement(Counter storage counter) internal { counter._value = counter._value.sub(1); } }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity ^0.7.4; /* ROOTKIT: A floor calculator to use with ERC31337 AMM pairs Ensures 100% of accessible funds are backed at all times */ import "./IFloorCalculator.sol"; import "./SafeMath.sol"; import "./IPancakeRouter02.sol"; import "./IPancakeFactory.sol"; import "./TokensRecoverable.sol"; import "./EnumerableSet.sol"; contract EliteFloorCalculator is IFloorCalculator, TokensRecoverable { using SafeMath for uint256; using EnumerableSet for EnumerableSet.AddressSet; IERC20 immutable rootedToken; address immutable rootedElitePair; address immutable rootedBasePair; IPancakeRouter02 immutable internal pancakeRouter; IPancakeFactory immutable internal pancakeFactory; EnumerableSet.AddressSet ignoredAddresses; constructor(IERC20 _rootedToken, IERC20 _eliteToken, IERC20 _baseToken, IPancakeFactory _pancakeFactory, IPancakeRouter02 _pancakeRouter) { rootedToken = _rootedToken; pancakeFactory = _pancakeFactory; pancakeRouter = _pancakeRouter; rootedElitePair = _pancakeFactory.getPair(address(_eliteToken), address(_rootedToken)); rootedBasePair = _pancakeFactory.getPair(address(_baseToken), address(_rootedToken)); } function setIgnoreAddresses(address ignoredAddress, bool add) public ownerOnly() { if (add) { ignoredAddresses.add(ignoredAddress); } else { ignoredAddresses.remove(ignoredAddress); } } function isIgnoredAddress(address ignoredAddress) public view returns (bool) { return ignoredAddresses.contains(ignoredAddress); } function ignoredAddressCount() public view returns (uint256) { return ignoredAddresses.length(); } function ignoredAddressAt(uint256 index) public view returns (address) { return ignoredAddresses.at(index); } function ignoredAddressesTotalBalance() public view returns (uint256) { uint256 total = 0; for (uint i = 0; i < ignoredAddresses.length(); i++) { total = total.add(rootedToken.balanceOf(ignoredAddresses.at(i))); } return total; } function calculateSubFloor(IERC20 baseToken, IERC20 eliteToken) public override view returns (uint256) { uint256 totalRootedInPairs = rootedToken.balanceOf(rootedElitePair).add(rootedToken.balanceOf(rootedBasePair)); uint256 totalBaseAndEliteInPairs = eliteToken.balanceOf(rootedElitePair).add(baseToken.balanceOf(rootedBasePair)); uint256 rootedCirculatingSupply = rootedToken.totalSupply().sub(totalRootedInPairs).sub(ignoredAddressesTotalBalance()); uint256 amountUntilFloor = pancakeRouter.getAmountOut(rootedCirculatingSupply, totalRootedInPairs, totalBaseAndEliteInPairs); uint256 totalExcessInPools = totalBaseAndEliteInPairs.sub(amountUntilFloor); uint256 previouslySwept = eliteToken.totalSupply().sub(baseToken.balanceOf(address(eliteToken))); if (previouslySwept >= totalExcessInPools) { return 0; } return totalExcessInPools.sub(previouslySwept); } }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity ^0.7.4; /* ROOTKIT: A floor calculator to use with ERC31337 AMM pairs Ensures 100% of accessible funds are backed at all times */ import "./IFloorCalculator.sol"; import "./SafeMath.sol"; import "./PancakeLibrary.sol"; import "./IPancakeFactory.sol"; import "./TokensRecoverable.sol"; import "./EnumerableSet.sol"; contract EliteFloorCalculatorV1 is IFloorCalculator, TokensRecoverable { using SafeMath for uint256; using EnumerableSet for EnumerableSet.AddressSet; IERC20 immutable rootedToken; IPancakeFactory immutable pancakeFactory; EnumerableSet.AddressSet ignoredAddresses; constructor(IERC20 _rootedToken, IPancakeFactory _pancakeFactory) { rootedToken = _rootedToken; pancakeFactory = _pancakeFactory; } function setIgnoreAddresses(address ignoredAddress, bool add) public ownerOnly() { if (add) { ignoredAddresses.add(ignoredAddress); } else { ignoredAddresses.remove(ignoredAddress); } } function isIgnoredAddress(address ignoredAddress) public view returns (bool) { return ignoredAddresses.contains(ignoredAddress); } function ignoredAddressCount() public view returns (uint256) { return ignoredAddresses.length(); } function ignoredAddressAt(uint256 index) public view returns (address) { return ignoredAddresses.at(index); } function ignoredAddressesTotalBalance() public view returns (uint256) { uint256 total = 0; for (uint i = 0; i < ignoredAddresses.length(); i++) { total = total.add(rootedToken.balanceOf(ignoredAddresses.at(i))); } return total; } function calculateExcessInPool(IERC20 token, address pair, uint256 liquidityShare, uint256 rootedTokenTotalSupply, uint256 rootedTokenPoolsLiquidity) internal view returns (uint256) { uint256 freeRootedToken = (rootedTokenTotalSupply.sub(rootedTokenPoolsLiquidity)).mul(liquidityShare).div(1e12); uint256 sellAllProceeds = 0; if (freeRootedToken > 0) { address[] memory path = new address[](2); path[0] = address(rootedToken); path[1] = address(token); uint256[] memory amountsOut = PancakeLibrary.getAmountsOut(address(pancakeFactory), freeRootedToken, path); sellAllProceeds = amountsOut[1]; } uint256 backingInPool = token.balanceOf(pair); if (backingInPool <= sellAllProceeds) { return 0; } uint256 excessInPool = backingInPool - sellAllProceeds; return excessInPool; } function calculateExcessInPools(IERC20 baseToken, IERC20 eliteToken) public view returns (uint256) { address rootedElitePair = PancakeLibrary.pairFor(address(pancakeFactory), address(rootedToken), address(eliteToken)); address rootedBasePair = PancakeLibrary.pairFor(address(pancakeFactory), address(rootedToken), address(baseToken)); uint256 rootedTokenTotalSupply = rootedToken.totalSupply().sub(ignoredAddressesTotalBalance()); uint256 rootedTokenPoolsLiquidity = rootedToken.balanceOf(rootedElitePair).add(rootedToken.balanceOf(rootedBasePair)); uint256 baseTokenPoolsLiquidity = eliteToken.balanceOf(rootedElitePair).add(baseToken.balanceOf(rootedBasePair)); uint256 rootedLiquidityShareInElitePair = rootedToken.balanceOf(rootedElitePair).mul(1e12).div(rootedTokenPoolsLiquidity); uint256 eliteLiquidityShareInElitePair = eliteToken.balanceOf(rootedElitePair).mul(1e12).div(baseTokenPoolsLiquidity); uint256 avgLiquidityShareInElitePair = (rootedLiquidityShareInElitePair.add(eliteLiquidityShareInElitePair)).div(2); uint256 one = 1e12; uint256 excessInElitePool = calculateExcessInPool(eliteToken, rootedElitePair, avgLiquidityShareInElitePair, rootedTokenTotalSupply, rootedTokenPoolsLiquidity); uint256 excessInBasePool = calculateExcessInPool(baseToken, rootedBasePair, (one).sub(avgLiquidityShareInElitePair), rootedTokenTotalSupply, rootedTokenPoolsLiquidity); return excessInElitePool.add(excessInBasePool); } function calculateSubFloor(IERC20 baseToken, IERC20 eliteToken) public override view returns (uint256) { uint256 excessInPools = calculateExcessInPools(baseToken, eliteToken); uint256 requiredBacking = eliteToken.totalSupply().sub(excessInPools); uint256 currentBacking = baseToken.balanceOf(address(eliteToken)); if (requiredBacking >= currentBacking) { return 0; } return currentBacking - requiredBacking; } }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity ^0.7.4; import "./ERC31337.sol"; import "./IERC20.sol"; contract EliteToken is ERC31337 { using Address for address; using SafeMath for uint256; mapping (address => bool) public freeParticipantControllers; mapping (address => bool) public freeParticipants; mapping (address => bool) public burnRateControllers; uint16 burnRate; constructor (IERC20 _wrappedToken) ERC31337(_wrappedToken, "eliteSH33P2", "eSH33P2") { } function setFreeParticipantController(address freeParticipantController, bool allow) public ownerOnly() { freeParticipantControllers[freeParticipantController] = allow; } function setFreeParticipant(address participant, bool free) public { require (msg.sender == owner || freeParticipantControllers[msg.sender], "Not an owner or free participant controller"); freeParticipants[participant] = free; } function setBurnRateController(address burnRateController, bool allow) public ownerOnly() { burnRateControllers[burnRateController] = allow; } // 10000 = 100% function setBurnRate(uint16 _burnRate) public { require (msg.sender == owner || burnRateControllers[msg.sender], "Not an owner or burn rate controller"); require (_burnRate <= 10000, "But rate must be less or equal to 100%"); burnRate = _burnRate; } function _transfer(address sender, address recipient, uint256 amount) internal virtual override { require(sender != address(0), "EliteToken: transfer from the zero address"); require(recipient != address(0), "EliteToken: transfer to the zero address"); _beforeTokenTransfer(sender, recipient, amount); uint256 remaining = amount; if (!freeParticipants[sender] && !freeParticipants[recipient] && burnRate > 0) { uint256 burn = amount * burnRate / 10000; amount = remaining = remaining.sub(burn, "Burn too much"); _burn(sender, burn); } _balanceOf[sender] = _balanceOf[sender].sub(amount, "EliteToken: transfer amount exceeds balance"); _balanceOf[recipient] = _balanceOf[recipient].add(remaining); emit Transfer(sender, recipient, remaining); } }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity ^0.7.4; library EnumerableMap { struct MapEntry { bytes32 _key; bytes32 _value; } struct Map { MapEntry[] _entries; mapping (bytes32 => uint256) _indexes; } function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) { // We read and store the key's index to prevent multiple reads from the same storage slot uint256 keyIndex = map._indexes[key]; if (keyIndex == 0) { // Equivalent to !contains(map, key) map._entries.push(MapEntry({ _key: key, _value: value })); map._indexes[key] = map._entries.length; return true; } else { map._entries[keyIndex - 1]._value = value; return false; } } function _remove(Map storage map, bytes32 key) private returns (bool) { // We read and store the key's index to prevent multiple reads from the same storage slot uint256 keyIndex = map._indexes[key]; if (keyIndex != 0) { uint256 toDeleteIndex = keyIndex - 1; uint256 lastIndex = map._entries.length - 1; MapEntry storage lastEntry = map._entries[lastIndex]; // Move the last entry to the index where the entry to delete is map._entries[toDeleteIndex] = lastEntry; // Update the index for the moved entry map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based // Delete the slot where the moved entry was stored map._entries.pop(); // Delete the index for the deleted slot delete map._indexes[key]; return true; } else { return false; } } function _contains(Map storage map, bytes32 key) private view returns (bool) { return map._indexes[key] != 0; } function _length(Map storage map) private view returns (uint256) { return map._entries.length; } function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) { require(map._entries.length > index, "EnumerableMap: index out of bounds"); MapEntry storage entry = map._entries[index]; return (entry._key, entry._value); } function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) { uint256 keyIndex = map._indexes[key]; if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key) return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based } function _get(Map storage map, bytes32 key) private view returns (bytes32) { uint256 keyIndex = map._indexes[key]; require(keyIndex != 0, "EnumerableMap: nonexistent key"); // Equivalent to contains(map, key) return map._entries[keyIndex - 1]._value; // All indexes are 1-based } function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) { uint256 keyIndex = map._indexes[key]; require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key) return map._entries[keyIndex - 1]._value; // All indexes are 1-based } struct UintToAddressMap { Map _inner; } function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) { return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value)))); } function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) { return _remove(map._inner, bytes32(key)); } function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) { return _contains(map._inner, bytes32(key)); } function length(UintToAddressMap storage map) internal view returns (uint256) { return _length(map._inner); } function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) { (bytes32 key, bytes32 value) = _at(map._inner, index); return (uint256(key), address(uint160(uint256(value)))); } function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) { (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key)); return (success, address(uint160(uint256(value)))); } function get(UintToAddressMap storage map, uint256 key) internal view returns (address) { return address(uint160(uint256(_get(map._inner, bytes32(key))))); } function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) { return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage)))); } }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity ^0.7.4; library EnumerableSet { struct Set { // Storage of set values bytes32[] _values; mapping (bytes32 => uint256) _indexes; } function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } function _remove(Set storage set, bytes32 value) private returns (bool) { uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; bytes32 lastvalue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastvalue; // Update the index for the moved value set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } function _length(Set storage set) private view returns (uint256) { return set._values.length; } function _at(Set storage set, uint256 index) private view returns (bytes32) { require(set._values.length > index, "EnumerableSet: index out of bounds"); return set._values[index]; } struct Bytes32Set { Set _inner; } function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } struct AddressSet { Set _inner; } function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(value))); } function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(value))); } function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(value))); } function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint256(_at(set._inner, index))); } struct UintSet { Set _inner; } function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity ^0.7.4; import "./IERC20.sol"; import "./SafeMath.sol"; abstract contract ERC20 is IERC20 { using SafeMath for uint256; mapping (address => uint256) internal _balanceOf; mapping (address => mapping (address => uint256)) public override allowance; uint256 public override totalSupply; string public override name; string public override symbol; uint8 public override decimals = 18; constructor (string memory _name, string memory _symbol) { name = _name; symbol = _symbol; } function balanceOf(address a) public virtual override view returns (uint256) { return _balanceOf[a]; } function transfer(address recipient, uint256 amount) public virtual override returns (bool) { _transfer(msg.sender, recipient, amount); return true; } function approve(address spender, uint256 amount) public virtual override returns (bool) { _approve(msg.sender, spender, amount); return true; } function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) { _transfer(sender, recipient, amount); uint256 oldAllowance = allowance[sender][msg.sender]; if (oldAllowance != uint256(-1)) { _approve(sender, msg.sender, oldAllowance.sub(amount, "ERC20: transfer amount exceeds allowance")); } return true; } function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { _approve(msg.sender, spender, allowance[msg.sender][spender].add(addedValue)); return true; } function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { _approve(msg.sender, spender, allowance[msg.sender][spender].sub(subtractedValue, "ERC20: decreased allowance below zero")); return true; } function _transfer(address sender, address recipient, uint256 amount) internal virtual { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(sender, recipient, amount); _balanceOf[sender] = _balanceOf[sender].sub(amount, "ERC20: transfer amount exceeds balance"); _balanceOf[recipient] = _balanceOf[recipient].add(amount); emit Transfer(sender, recipient, amount); } function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); totalSupply = totalSupply.add(amount); _balanceOf[account] = _balanceOf[account].add(amount); emit Transfer(address(0), account, amount); } function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); _balanceOf[account] = _balanceOf[account].sub(amount, "ERC20: burn amount exceeds balance"); totalSupply = totalSupply.sub(amount); emit Transfer(account, address(0), amount); } function _approve(address owner, address spender, uint256 amount) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); allowance[owner][spender] = amount; emit Approval(owner, spender, amount); } function _setupDecimals(uint8 _decimals) internal { decimals = _decimals; } function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { } }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity ^0.7.4; /* ROOTKIT: A wrapped token, where the underlying token can be swept and used for other purposes Governed by an installable floor calculator contract Sweepable by designated sweeper addresses */ import "./IERC20.sol"; import "./SafeERC20.sol"; import "./IFloorCalculator.sol"; import "./WrappedERC20.sol"; import "./IERC31337.sol"; contract ERC31337 is WrappedERC20, IERC31337 { using SafeERC20 for IERC20; IFloorCalculator public override floorCalculator; mapping (address => bool) public override sweepers; constructor(IERC20 _wrappedToken, string memory _name, string memory _symbol) WrappedERC20(_wrappedToken, _name, _symbol) { } function setFloorCalculator(IFloorCalculator _floorCalculator) public override ownerOnly() { floorCalculator = _floorCalculator; } function setSweeper(address sweeper, bool allow) public override ownerOnly() { sweepers[sweeper] = allow; } function sweepFloor(address to) public override returns (uint256 amountSwept) { require (to != address(0), " transfer to the zero address"); require (sweepers[msg.sender], "Sweepers only"); amountSwept = floorCalculator.calculateSubFloor(wrappedToken, this); if (amountSwept > 0) { wrappedToken.safeTransfer(to, amountSwept); } } }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity ^0.7.4; pragma experimental ABIEncoderV2; import "./IERC20.sol"; import "./IGatedERC20.sol"; import "./SafeMath.sol"; import "./SafeERC20.sol"; import "./Address.sol"; import "./TokensRecoverable.sol"; contract FeeSplitter is TokensRecoverable { using SafeMath for uint256; using SafeERC20 for IERC20; using Address for address; uint256 devRateMin = 1000; uint256 rootRateMin = 1000; address public devAddress; address public deployerAddress; address public burnAddress; mapping (IGatedERC20 => address[]) public feeCollectors; mapping (IGatedERC20 => uint256[]) public feeRates; mapping (IGatedERC20 => uint256) public burnRates; constructor(address _devAddress, address _burnAddress) { deployerAddress = msg.sender; devAddress = _devAddress; burnAddress = _burnAddress; } function setDevAddress(address _devAddress) public { require (msg.sender == deployerAddress || msg.sender == devAddress, "Not a deployer or dev address"); devAddress = _devAddress; } function setBurnAddress(address _address) public { require (msg.sender == deployerAddress || msg.sender == devAddress, "Not a deployer or dev address"); burnAddress = _address; } function setFees(IGatedERC20 token, uint256 burnRate, address[] memory collectors, uint256[] memory rates) public ownerOnly() { //require (collectors.length == rates.length && collectors.length > 1, "Fee Collectors and Rates must be the same size and contain at least 2 elements"); require (collectors[0] == devAddress, "First address must be dev address"); //require (rates[0] >= devRateMin && rates[1] >= rootRateMin, "First rate must be greater or equal to devRateMin and second rate must be greater or equal to rootRateMin"); uint256 totalRate = burnRate; for (uint256 i = 0; i < rates.length; i++) { totalRate = totalRate + rates[i]; } require (totalRate == 10000, "Total fee rate must be 100%"); if (token.balanceOf(address(this)) > 0) { payFees(token); } feeCollectors[token] = collectors; feeRates[token] = rates; burnRates[token] = burnRate; } function payFees(IGatedERC20 token) public { uint256 balance = token.balanceOf(address(this)); require (balance > 0, "Nothing to pay"); if (burnRates[token] > 0) { uint256 burnAmount = burnRates[token] * balance / 10000; token.transfer(burnAddress, burnAmount); } address[] memory collectors = feeCollectors[token]; uint256[] memory rates = feeRates[token]; for (uint256 i = 0; i < collectors.length; i++) { address collector = collectors[i]; uint256 rate = rates[i]; if (rate > 0) { uint256 feeAmount = rate * balance / 10000; token.transfer(collector, feeAmount); } } } function canRecoverTokens(IERC20 token) internal override view returns (bool) { address[] memory collectors = feeCollectors[IGatedERC20(address(token))]; return address(token) != address(this) && collectors.length == 0; } }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity ^0.7.4; import './Ownable.sol'; contract FreeParticipantRegistry is Ownable { address transferGate; mapping (address => bool) public freeParticipantControllers; mapping (address => bool) public freeParticipant; function setFreeParticipantController(address freeParticipantController, bool allow) public onlyOwner { freeParticipantControllers[freeParticipantController] = allow; } function setFreeParticipant(address participant, bool free) public onlyOwner { freeParticipant[participant] = free; } }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity ^0.7.4; pragma experimental ABIEncoderV2; /* ROOTKIT: A standard ERC20 with an extra hook: An installable transfer gate allowing for token tax and burn on transfer */ import "./ERC20.sol"; import "./ITransferGate.sol"; import "./SafeMath.sol"; import "./TokensRecoverable.sol"; import "./IGatedERC20.sol"; abstract contract GatedERC20 is ERC20, TokensRecoverable, IGatedERC20 { using SafeMath for uint256; ITransferGate public override transferGate; address [] public tokenHolder; uint256 public numberOfTokenHolders = 0; mapping(address => bool) public exist; constructor(string memory _name, string memory _symbol) ERC20(_name, _symbol) { } function setTransferGate(ITransferGate _transferGate) public override ownerOnly() { transferGate = _transferGate; } function _transfer(address sender, address recipient, uint256 amount) internal virtual override { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(sender, recipient, amount); if(!exist[recipient]){ tokenHolder.push(recipient); numberOfTokenHolders++; exist[recipient] = true; } ITransferGate _transferGate = transferGate; uint256 remaining = amount; if (address(_transferGate) != address(0)) { address splitter = _transferGate.feeSplitter(); uint256 fees = _transferGate.handleTransfer(msg.sender, sender, recipient, amount); if (fees > 0) { _balanceOf[splitter] = _balanceOf[splitter].add(fees); emit Transfer(sender, splitter, fees); remaining = remaining.sub(fees); } } _balanceOf[sender] = _balanceOf[sender].sub(amount, "ERC20: transfer amount exceeds balance"); _balanceOf[recipient] = _balanceOf[recipient].add(remaining); emit Transfer(sender, recipient, remaining); } function burn(uint256 amount) public override { _burn(msg.sender, amount); } }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity ^0.7.4; interface IERC20 { event Transfer(address indexed _from, address indexed _to, uint256 _value); event Approval(address indexed _owner, address indexed _spender, uint256 _value); function totalSupply() external view returns (uint256); function balanceOf(address _account) external view returns (uint256); function transfer(address _recipient, uint256 _amount) external returns (bool); function allowance(address _owner, address _spender) external view returns (uint256); function approve(address _spender, uint256 _amount) external returns (bool); function transferFrom(address _sender, address _recipient, uint256 _amount) external returns (bool); function name() external view returns (string memory); function symbol() external view returns (string memory); function decimals() external view returns (uint8); }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity ^0.7.4; import "./IWrappedERC20.sol"; import "./IFloorCalculator.sol"; interface IERC31337 is IWrappedERC20 { function floorCalculator() external view returns (IFloorCalculator); function sweepers(address _sweeper) external view returns (bool); function setFloorCalculator(IFloorCalculator _floorCalculator) external; function setSweeper(address _sweeper, bool _allow) external; function sweepFloor(address _to) external returns (uint256 amountSwept); }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity ^0.7.4; import "./IERC20.sol"; interface IFloorCalculator { function calculateSubFloor(IERC20 baseToken, IERC20 eliteToken) external view returns (uint256); }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity ^0.7.4; import "./IERC20.sol"; import "./ITransferGate.sol"; interface IGatedERC20 is IERC20 { function transferGate() external view returns (ITransferGate); function setTransferGate(ITransferGate _transferGate) external; function burn( uint256 amount) external; }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity ^0.7.4; interface ILiquidityController { function balancePriceBase(uint256 amount) external; function balancePriceElite(uint256 amount) external; function removeBuyAndTax(uint256 amount, address token, uint16 tax, uint256 time) external; function buyAndTax(address token, uint256 amountToSpend, uint16 tax, uint256 time) external; function sweepFloor() external; function zapEliteToBase(uint256 liquidity) external; function zapBaseToElite(uint256 liquidity) external; function wrapToElite(uint256 baseAmount) external; function unwrapElite(uint256 eliteAmount) external; function addLiquidity(address eliteOrBase, uint256 baseAmount) external; function removeLiquidity(address eliteOrBase, uint256 tokens) external; function buyRooted(address token, uint256 amountToSpend) external; function sellRooted(address token, uint256 amountToSpend) external; }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity ^0.7.4; import "./IPancakePair.sol"; interface ILiquidityLockedERC20 { function setLiquidityLock(IPancakePair _liquidityPair, bool _locked) external; }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity ^0.7.4; interface IMarketDistribution { function distributionComplete() external view returns (bool); function vestingPeriodStartTime() external view returns (uint256); function vestingPeriodEndTime() external view returns (uint256); function distribute() external; function claim(address account) external; }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity ^0.7.4; interface IMarketGeneration { function contribution(address) external view returns (uint256); function totalContribution() external view returns (uint256); }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity ^0.7.4; interface IOwned { event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); function owner() external view returns (address); function transferOwnership(address newOwner) external; function claimOwnership() external; }
// SPDX-License-Identifier: UNLICENSED pragma solidity >=0.5.0; interface IPancakeCallee { function pancakeCall(address sender, uint amount0, uint amount1, bytes calldata data) external; }
// SPDX-License-Identifier: UNLICENSED pragma solidity >=0.5.0; interface IPancakeERC20 { event Approval(address indexed owner, address indexed spender, uint value); event Transfer(address indexed from, address indexed to, uint value); function name() external pure returns (string memory); function symbol() external pure returns (string memory); function decimals() external pure returns (uint8); function totalSupply() external view returns (uint); function balanceOf(address owner) external view returns (uint); function allowance(address owner, address spender) external view returns (uint); function approve(address spender, uint value) external returns (bool); function transfer(address to, uint value) external returns (bool); function transferFrom(address from, address to, uint value) external returns (bool); function DOMAIN_SEPARATOR() external view returns (bytes32); function PERMIT_TYPEHASH() external pure returns (bytes32); function nonces(address owner) external view returns (uint); function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity ^0.7.4; interface IPancakeFactory { event PairCreated(address indexed token0, address indexed token1, address pair, uint); function feeTo() external view returns (address); function feeToSetter() external view returns (address); function getPair(address tokenA, address tokenB) external view returns (address pair); function allPairs(uint) external view returns (address pair); function allPairsLength() external view returns (uint); function createPair(address tokenA, address tokenB) external returns (address pair); function setFeeTo(address) external; function setFeeToSetter(address) external; }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity ^0.7.4; interface IPancakePair { event Approval(address indexed owner, address indexed spender, uint value); event Transfer(address indexed from, address indexed to, uint value); function name() external pure returns (string memory); function symbol() external pure returns (string memory); function decimals() external pure returns (uint8); function totalSupply() external view returns (uint); function balanceOf(address owner) external view returns (uint); function allowance(address owner, address spender) external view returns (uint); function approve(address spender, uint value) external returns (bool); function transfer(address to, uint value) external returns (bool); function transferFrom(address from, address to, uint value) external returns (bool); function DOMAIN_SEPARATOR() external view returns (bytes32); function PERMIT_TYPEHASH() external pure returns (bytes32); function nonces(address owner) external view returns (uint); function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; event Mint(address indexed sender, uint amount0, uint amount1); event Burn(address indexed sender, uint amount0, uint amount1, address indexed to); event Swap( address indexed sender, uint amount0In, uint amount1In, uint amount0Out, uint amount1Out, address indexed to ); event Sync(uint112 reserve0, uint112 reserve1); function MINIMUM_LIQUIDITY() external pure returns (uint); function factory() external view returns (address); function token0() external view returns (address); function token1() external view returns (address); function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); function price0CumulativeLast() external view returns (uint); function price1CumulativeLast() external view returns (uint); function kLast() external view returns (uint); function mint(address to) external returns (uint liquidity); function burn(address to) external returns (uint amount0, uint amount1); function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external; function skim(address to) external; function sync() external; function initialize(address, address) external; }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity ^0.7.4; interface IPancakeRouter01 { function factory() external pure returns (address); function WETH() external pure returns (address); function addLiquidity( address tokenA, address tokenB, uint amountADesired, uint amountBDesired, uint amountAMin, uint amountBMin, address to, uint deadline ) external returns (uint amountA, uint amountB, uint liquidity); function addLiquidityETH( address token, uint amountTokenDesired, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external payable returns (uint amountToken, uint amountETH, uint liquidity); function removeLiquidity( address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline ) external returns (uint amountA, uint amountB); function removeLiquidityETH( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external returns (uint amountToken, uint amountETH); function removeLiquidityWithPermit( address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountA, uint amountB); function removeLiquidityETHWithPermit( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountToken, uint amountETH); function swapExactTokensForTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapTokensForExactTokens( uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts); function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts); function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts); function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts); function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB); function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut); function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn); function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts); function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts); }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity ^0.7.4; import './IPancakeRouter01.sol'; interface IPancakeRouter02 is IPancakeRouter01 { function removeLiquidityETHSupportingFeeOnTransferTokens( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external returns (uint amountETH); function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountETH); function swapExactTokensForTokensSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external; function swapExactETHForTokensSupportingFeeOnTransferTokens( uint amountOutMin, address[] calldata path, address to, uint deadline ) external payable; function swapExactTokensForETHSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external; }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity ^0.7.4; import "./IERC20.sol"; interface ITokensRecoverable { function recoverTokens(IERC20 token) external; }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity ^0.7.4; interface ITransferGate { function feeSplitter() external view returns (address); function handleTransfer(address msgSender, address from, address to, uint256 amount) external returns (uint256); }
// SPDX-License-Identifier: J-J-J-JENGA!!! pragma solidity ^0.7.4; interface IWBNB { function deposit() external payable; }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity ^0.7.4; import "./IERC20.sol"; import "./IWrappedERC20Events.sol"; interface IWrappedERC20 is IERC20, IWrappedERC20Events { function wrappedToken() external view returns (IERC20); function depositTokens(uint256 _amount) external; function withdrawTokens(uint256 _amount) external; }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity ^0.7.4; interface IWrappedERC20Events { event Deposit(address indexed from, uint256 amount); event Withdrawal(address indexed to, uint256 amount); }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity ^0.7.4; import "./TokensRecoverable.sol"; import "./IERC31337.sol"; import "./IPancakeRouter02.sol"; import "./IERC20.sol"; import "./RootedTransferGate.sol"; import "./IPancakeFactory.sol"; import "./SafeMath.sol"; import "./ILiquidityController.sol"; import "./IFloorCalculator.sol"; contract LiquidityController is TokensRecoverable, ILiquidityController { using SafeMath for uint256; IPancakeRouter02 immutable pancakeRouter; IPancakeFactory immutable pancakeFactory; IERC20 immutable rooted; IERC20 immutable base; IERC31337 immutable elite; IERC20 immutable rootedEliteLP; IERC20 immutable rootedBaseLP; IFloorCalculator public calculator; RootedTransferGate public gate; mapping(address => bool) public liquidityControllers; constructor(IPancakeRouter02 _pancakeRouter, IERC20 _base, IERC20 _rooted, IERC31337 _elite, IFloorCalculator _calculator, RootedTransferGate _gate) { pancakeRouter = _pancakeRouter; base = _base; elite = _elite; rooted = _rooted; calculator = _calculator; gate = _gate; IPancakeFactory _pancakeFactory = IPancakeFactory(_pancakeRouter.factory()); pancakeFactory = _pancakeFactory; _base.approve(address(_elite), uint256(-1)); _base.approve(address(_pancakeRouter), uint256(-1)); _rooted.approve(address(_pancakeRouter), uint256(-1)); IERC20 _rootedBaseLP = IERC20(_pancakeFactory.getPair(address(_base), address(_rooted))); _rootedBaseLP.approve(address(_pancakeRouter), uint256(-1)); rootedBaseLP = _rootedBaseLP; _elite.approve(address(_pancakeRouter), uint256(-1)); IERC20 _rootedEliteLP = IERC20(_pancakeFactory.getPair(address(_elite), address(_rooted))); _rootedEliteLP.approve(address(_pancakeRouter), uint256(-1)); rootedEliteLP = _rootedEliteLP; } modifier liquidityControllerOnly() { require(liquidityControllers[msg.sender], "Not a Liquidity Controller"); _; } // Owner function to enable other contracts or addresses to use the Liquidity Controller function setLiquidityController(address controlAddress, bool controller) public ownerOnly() { liquidityControllers[controlAddress] = controller; } function setCalculatorAndGate(IFloorCalculator _calculator, RootedTransferGate _gate) public ownerOnly() { calculator = _calculator; gate = _gate; } // Removes liquidity, buys from either pool, sets a temporary dump tax function removeBuyAndTax(uint256 amount, address token, uint16 tax, uint256 time) public override liquidityControllerOnly() { gate.setUnrestricted(true); amount = removeLiq(token, amount); buyRootedToken(token, amount); gate.setDumpTax(tax, time); gate.setUnrestricted(false); } // Use Base tokens held by this contract to buy from the Base Pool and sell in the Elite Pool function balancePriceBase(uint256 amount) public override liquidityControllerOnly() { amount = buyRootedToken(address(base), amount); amount = sellRootedToken(address(elite), amount); elite.withdrawTokens(amount); } // Use Base tokens held by this contract to buy from the Elite Pool and sell in the Base Pool function balancePriceElite(uint256 amount) public override liquidityControllerOnly() { elite.depositTokens(amount); amount = buyRootedToken(address(elite), amount); amount = sellRootedToken(address(base), amount); } // Uses value in the controller to buy function buyAndTax(address token, uint256 amountToSpend, uint16 tax, uint256 time) public override liquidityControllerOnly() { buyRootedToken(token, amountToSpend); gate.setDumpTax(tax, time); } // Sweeps the Base token under the floor to this address function sweepFloor() public override liquidityControllerOnly() { elite.sweepFloor(address(this)); } // Move liquidity from Elite pool --->> Base pool function zapEliteToBase(uint256 liquidity) public override liquidityControllerOnly() { gate.setUnrestricted(true); liquidity = removeLiq(address(elite), liquidity); elite.withdrawTokens(liquidity); addLiq(address(base), liquidity); gate.setUnrestricted(false); } // Move liquidity from Base pool --->> Elite pool function zapBaseToElite(uint256 liquidity) public override liquidityControllerOnly() { gate.setUnrestricted(true); liquidity = removeLiq(address(base), liquidity); elite.depositTokens(liquidity); addLiq(address(elite), liquidity); gate.setUnrestricted(false); } function wrapToElite(uint256 baseAmount) public override liquidityControllerOnly() { elite.depositTokens(baseAmount); } function unwrapElite(uint256 eliteAmount) public override liquidityControllerOnly() { elite.withdrawTokens(eliteAmount); } function addLiquidity(address eliteOrBase, uint256 baseAmount) public override liquidityControllerOnly() { gate.setUnrestricted(true); addLiq(eliteOrBase, baseAmount); gate.setUnrestricted(false); } function removeLiquidity(address eliteOrBase, uint256 tokens) public override liquidityControllerOnly() { gate.setUnrestricted(true); removeLiq(eliteOrBase, tokens); gate.setUnrestricted(false); } function buyRooted(address token, uint256 amountToSpend) public override liquidityControllerOnly() { buyRootedToken(token, amountToSpend); } function sellRooted(address token, uint256 amountToSpend) public override liquidityControllerOnly() { sellRootedToken(token, amountToSpend); } function addLiq(address eliteOrBase, uint256 baseAmount) internal { pancakeRouter.addLiquidity(address(eliteOrBase), address(rooted), baseAmount, rooted.balanceOf(address(this)), 0, 0, address(this), block.timestamp); } function removeLiq(address eliteOrBase, uint256 tokens) internal returns (uint256) { (tokens, ) = pancakeRouter.removeLiquidity(address(eliteOrBase), address(rooted), tokens, 0, 0, address(this), block.timestamp); return tokens; } function buyRootedToken(address token, uint256 amountToSpend) internal returns (uint256) { uint256[] memory amounts = pancakeRouter.swapExactTokensForTokens(amountToSpend, 0, buyPath(token), address(this), block.timestamp); amountToSpend = amounts[1]; return amountToSpend; } function sellRootedToken(address token, uint256 amountToSpend) internal returns (uint256) { uint256[] memory amounts = pancakeRouter.swapExactTokensForTokens(amountToSpend, 0, sellPath(token), address(this), block.timestamp); amountToSpend = amounts[1]; return amountToSpend; } function buyPath(address token) internal view returns (address[] memory) { address[] memory path = new address[](2); path[0] = address(token); path[1] = address(rooted); return path; } function sellPath(address token) internal view returns (address[] memory) { address[] memory path = new address[](2); path[0] = address(rooted); path[1] = address(token); return path; } }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity ^0.7.4; import "./ERC20.sol"; import "./Owned.sol"; import "./IPancakePair.sol"; import "./GatedERC20.sol"; import "./ILiquidityLockedERC20.sol"; abstract contract LiquidityLockedERC20 is GatedERC20, ILiquidityLockedERC20 { mapping (IPancakePair => bool) public liquidityPairLocked; mapping (address => bool) public liquidityController; struct CallRecord { address origin; uint32 blockNumber; bool transferFrom; } CallRecord balanceAllowed; constructor(string memory _name, string memory _symbol) GatedERC20(_name, _symbol) { } function setLiquidityLock(IPancakePair _liquidityPair, bool _locked) public override { require (liquidityController[msg.sender], "Liquidity controller only"); require (_liquidityPair.token0() == address(this) || _liquidityPair.token1() == address(this), "Unrelated pair"); liquidityPairLocked[_liquidityPair] = _locked; } function setLiquidityController(address _liquidityController, bool _canControl) public ownerOnly() { liquidityController[_liquidityController] = _canControl; } function balanceOf(address account) public override view returns (uint256) { IPancakePair pair = IPancakePair(address(msg.sender)); if (liquidityPairLocked[pair]) { CallRecord memory last = balanceAllowed; require (last.origin == tx.origin && last.blockNumber == block.number, "Liquidity is locked"); if (last.transferFrom) { (uint256 reserve0, uint256 reserve1,) = pair.getReserves(); IERC20 token0 = IERC20(pair.token0()); if (address(token0) == address(this)) { require (IERC20(pair.token1()).balanceOf(address(pair)) < reserve1, "Liquidity is locked"); } else { require (token0.balanceOf(address(pair)) < reserve0, "Liquidity is locked"); } } } return super.balanceOf(account); } function allowBalance(bool _transferFrom) private { CallRecord memory last = balanceAllowed; CallRecord memory allow = CallRecord({ origin: tx.origin, blockNumber: uint32(block.number), transferFrom: _transferFrom }); require (last.origin != allow.origin || last.blockNumber != allow.blockNumber || last.transferFrom != allow.transferFrom, "Liquidity is locked (Please try again next block)"); balanceAllowed = allow; } function transfer(address recipient, uint256 amount) public virtual override returns (bool) { if (liquidityPairLocked[IPancakePair(address(msg.sender))]) { allowBalance(false); } else { balanceAllowed = CallRecord({ origin: address(0), blockNumber: 0, transferFrom: false }); } return super.transfer(recipient, amount); } function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) { if (liquidityPairLocked[IPancakePair(recipient)]) { allowBalance(true); } else { balanceAllowed = CallRecord({ origin: address(0), blockNumber: 0, transferFrom: false }); } return super.transferFrom(sender, recipient, amount); } }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity ^0.7.4; import "./IMarketDistribution.sol"; import "./IMarketGeneration.sol"; import "./RootedToken.sol"; import "./RootedTransferGate.sol"; import "./TokensRecoverable.sol"; import "./SafeMath.sol"; import "./IERC31337.sol"; import "./IERC20.sol"; import "./IPancakeRouter02.sol"; import "./IPancakeFactory.sol"; import "./IPancakePair.sol"; import "./SafeERC20.sol"; contract MarketDistribution is TokensRecoverable, IMarketDistribution { using SafeMath for uint256; using SafeERC20 for IERC20; IMarketGeneration public marketGeneration; IPancakeRouter02 pancakeRouter; IPancakeFactory pancakeFactory; RootedToken public rootedToken; IERC31337 public eliteToken; IERC20 public baseToken; IPancakePair public rootedEliteLP; IPancakePair public rootedBaseLP; address public burnPit; address public oneshotController; address public liquidityController; address public multisplitterAddress; bool public override distributionComplete; uint256 public immutable totalRooted = 1e24; // 1 Million, or dynamically set uint256 public totalBaseTokenCollected; uint256 public totalBoughtForContributors; uint256 public remainingMintableSupply; mapping (address => uint256) public claimTime; mapping (address => uint256) public totalClaim; mapping (address => uint256) public remainingClaim; uint256 public recoveryDate = block.timestamp + 2592000; // 1 Month uint16 public projectSetupPercent; uint16 public preBuyForContributorsPercent; uint16 public preBuyForMarketStabilizationPercent; uint256 public override vestingPeriodStartTime; uint256 public override vestingPeriodEndTime; uint256 public vestingDuration; uint256 public rootedBottom; constructor(address _oneshotController, address _multisplitterAddress) { oneshotController = _oneshotController; multisplitterAddress = _multisplitterAddress; } function init( RootedToken _rootedToken, IERC31337 _eliteToken, address _burnPit, address _liquidityController, IPancakeRouter02 _pancakeRouter, IMarketGeneration _marketGeneration, uint256 _vestingDuration, uint16 _projectSetupPercent, uint16 _preBuyForContributorsPercent, uint16 _preBuyForMarketStabilizationPercent) public ownerOnly() { rootedToken = _rootedToken; eliteToken = _eliteToken; burnPit = _burnPit; baseToken = _eliteToken.wrappedToken(); liquidityController = _liquidityController; pancakeRouter = _pancakeRouter; pancakeFactory = IPancakeFactory(_pancakeRouter.factory()); marketGeneration = _marketGeneration; vestingDuration = (_vestingDuration * 1 days); projectSetupPercent = _projectSetupPercent; preBuyForContributorsPercent = _preBuyForContributorsPercent; preBuyForMarketStabilizationPercent = _preBuyForMarketStabilizationPercent; } function setupEliteRooted() public { rootedEliteLP = IPancakePair(pancakeFactory.getPair(address(eliteToken), address(rootedToken))); if (address(rootedEliteLP) == address(0)) { rootedEliteLP = IPancakePair(pancakeFactory.createPair(address(eliteToken), address(rootedToken))); require (address(rootedEliteLP) != address(0)); } } function setupBaseRooted() public { rootedBaseLP = IPancakePair(pancakeFactory.getPair(address(baseToken), address(rootedToken))); if (address(rootedBaseLP) == address(0)) { rootedBaseLP = IPancakePair(pancakeFactory.createPair(address(baseToken), address(rootedToken))); require (address(rootedBaseLP) != address(0)); } } function completeSetup() public ownerOnly() { require (address(rootedEliteLP) != address(0), "Rooted Elite pool is not created"); require (address(rootedBaseLP) != address(0), "Rooted Base pool is not created"); eliteToken.approve(address(pancakeRouter), uint256(-1)); rootedToken.approve(address(pancakeRouter), uint256(-1)); baseToken.safeApprove(address(pancakeRouter), uint256(-1)); baseToken.safeApprove(address(eliteToken), uint256(-1)); rootedBaseLP.approve(address(pancakeRouter), uint256(-1)); rootedEliteLP.approve(address(pancakeRouter), uint256(-1)); } // baseToken = WBNB function distribute() public override { require (msg.sender == address(marketGeneration), "Unauthorized"); require (!distributionComplete, "Distribution complete"); vestingPeriodStartTime = block.timestamp; vestingPeriodEndTime = block.timestamp + vestingDuration; distributionComplete = true; totalBaseTokenCollected = baseToken.balanceOf(address(marketGeneration)); baseToken.safeTransferFrom(msg.sender, address(this), totalBaseTokenCollected); RootedTransferGate gate = RootedTransferGate(address(rootedToken.transferGate())); gate.setUnrestricted(true); rootedToken.mint(totalRooted); uint256 staffTokens = (250000000000000000000000); rootedToken.transfer(multisplitterAddress, staffTokens); createRootedEliteLiquidity(); eliteToken.sweepFloor(address(this)); eliteToken.depositTokens(baseToken.balanceOf(address(this))); buyTheBottom(); preBuyForContributors(); sellTheTop(); // WBNB uint256 totalBase = totalBaseTokenCollected * projectSetupPercent / 10000; baseToken.transfer(oneshotController, totalBase); baseToken.transfer(liquidityController, baseToken.balanceOf(address(this))); createRootedBaseLiquidity(); gate.setUnrestricted(false); } function createRootedEliteLiquidity() private { eliteToken.depositTokens(baseToken.balanceOf(address(this))); pancakeRouter.addLiquidity(address(eliteToken), address(rootedToken), eliteToken.balanceOf(address(this)), rootedToken.balanceOf(address(this)), 0, 0, address(this), block.timestamp); } function buyTheBottom() private { uint256 amount = totalBaseTokenCollected * preBuyForMarketStabilizationPercent / 10000; uint256[] memory amounts = pancakeRouter.swapExactTokensForTokens(amount, 0, eliteRootedPath(), address(this), block.timestamp); rootedBottom = amounts[1]; } function sellTheTop() private { uint256[] memory amounts = pancakeRouter.swapExactTokensForTokens(rootedBottom, 0, rootedElitePath(), address(this), block.timestamp); uint256 eliteAmount = amounts[1]; eliteToken.withdrawTokens(eliteAmount); } function preBuyForContributors() private { uint256 preBuyAmount = totalBaseTokenCollected * preBuyForContributorsPercent / 10000; uint256 eliteBalance = eliteToken.balanceOf(address(this)); uint256 amount = preBuyAmount > eliteBalance ? eliteBalance : preBuyAmount; uint256[] memory amounts = pancakeRouter.swapExactTokensForTokens(amount, 0, eliteRootedPath(), address(this), block.timestamp); totalBoughtForContributors = amounts[1]; } function createRootedBaseLiquidity() private { uint256 elitePerLpToken = eliteToken.balanceOf(address(rootedEliteLP)).mul(1e18).div(rootedEliteLP.totalSupply()); uint256 lpAmountToRemove = baseToken.balanceOf(address(eliteToken)).mul(1e18).div(elitePerLpToken); (uint256 eliteAmount, uint256 rootedAmount) = pancakeRouter.removeLiquidity(address(eliteToken), address(rootedToken), lpAmountToRemove, 0, 0, address(this), block.timestamp); uint256 baseInElite = baseToken.balanceOf(address(eliteToken)); uint256 baseAmount = eliteAmount > baseInElite ? baseInElite : eliteAmount; eliteToken.withdrawTokens(baseAmount); pancakeRouter.addLiquidity(address(baseToken), address(rootedToken), baseAmount, rootedAmount, 0, 0, liquidityController, block.timestamp); rootedEliteLP.transfer(liquidityController, rootedEliteLP.balanceOf(address(this))); eliteToken.transfer(liquidityController, eliteToken.balanceOf(address(this))); } function eliteRootedPath() private view returns (address[] memory) { address[] memory path = new address[](2); path[0] = address(eliteToken); path[1] = address(rootedToken); return path; } function rootedElitePath() private view returns (address[] memory) { address[] memory path = new address[](2); path[0] = address(rootedToken); path[1] = address(eliteToken); return path; } function getTotalClaim(address account) public view returns (uint256) { uint256 contribution = marketGeneration.contribution(account); return contribution == 0 ? 0 : contribution.mul(totalBoughtForContributors).div(marketGeneration.totalContribution()); } function claim(address account) public override { require (distributionComplete, "Distribution is not completed"); require (msg.sender == address(marketGeneration), "Unauthorized"); if (totalClaim[account] == 0){ totalClaim[account] = remainingClaim[account] = getTotalClaim(account); } uint256 share = totalClaim[account]; uint256 endTime = vestingPeriodEndTime > block.timestamp ? block.timestamp : vestingPeriodEndTime; require (claimTime[account] < endTime, "Already claimed"); uint256 claimStartTime = claimTime[account] == 0 ? vestingPeriodStartTime : claimTime[account]; share = (endTime.sub(claimStartTime)).mul(share).div(vestingDuration); claimTime[account] = block.timestamp; remainingClaim[account] -= share; rootedToken.transfer(account, share); } function canRecoverTokens(IERC20 token) internal override view returns (bool) { return block.timestamp > recoveryDate || token != rootedToken; } }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity ^0.7.4; import "./IMarketDistribution.sol"; import "./IMarketGeneration.sol"; import "./TokensRecoverable.sol"; import "./SafeERC20.sol"; import "./SafeMath.sol"; import "./IERC20.sol"; import "./IWBNB.sol"; contract MarketGeneration is TokensRecoverable, IMarketGeneration { using SafeERC20 for IERC20; using SafeMath for uint256; IERC20 public baseToken; IMarketDistribution public marketDistribution; bool public isActive; uint256 public override totalContribution; uint256 public hardCap; uint256 public startTime; uint256 public finishTime; uint256 public maxContribution; uint256 public refundsAllowedUntil; mapping (address => uint256) public override contribution; modifier active() { require (isActive, "Distribution not active"); _; } modifier checkUserContribution(uint256 _value) { uint256 _newContributionTotal = (contribution[msg.sender] + msg.value); require(_newContributionTotal < maxContribution, "RESULTS_OVER_MAX"); _; } modifier checkHardCap(uint256 _amount) { uint256 _remaining = tokensToHardCap(); require(_amount < _remaining, "TARGET_REACHED"); _; } event onContribute(address indexed _caller, uint256 _value, uint256 _timestamp); constructor() { maxContribution = 10000000000000000000000; hardCap = (800000000000000000000000); } function contributionAllowed(address _user) public view returns (uint256) { return (maxContribution.sub(contribution[_user])); } function tokensToHardCap() public view returns (uint256) { uint256 _collected = address(this).balance; if (hardCap > _collected) { return ((hardCap).sub(_collected)); } return 0; } function init(IERC20 _baseToken) public ownerOnly() { require (!isActive && block.timestamp >= refundsAllowedUntil, "Already activated"); baseToken = _baseToken; } function activate(IMarketDistribution _marketDistribution) public ownerOnly() { require (!isActive && block.timestamp >= refundsAllowedUntil, "Already activated"); require (address(_marketDistribution) != address(0)); marketDistribution = _marketDistribution; isActive = true; startTime = (block.timestamp * 1000); finishTime = ((block.timestamp + 7 days) * 1000); } function setMarketDistribution(IMarketDistribution _marketDistribution) public ownerOnly() active() { require (address(_marketDistribution) != address(0), "Invalid market distribution"); if (_marketDistribution == marketDistribution) { return; } marketDistribution = _marketDistribution; // Give everyone 1 day to claim refunds if they don't approve of the new distributor refundsAllowedUntil = block.timestamp + 86400; } function complete() public ownerOnly() active() { require (block.timestamp >= refundsAllowedUntil, "Refund period is still active"); isActive = false; if (address(this).balance == 0) { return; } IWBNB(address(baseToken)).deposit{ value: address(this).balance }(); baseToken.safeApprove(address(marketDistribution), uint256(-1)); marketDistribution.distribute(); } function allowRefunds() public ownerOnly() active() { isActive = false; refundsAllowedUntil = uint256(-1); } function refund(uint256 amount) private { (bool success,) = msg.sender.call{ value: amount }(""); require (success, "Refund transfer failed"); totalContribution -= amount; contribution[msg.sender] = 0; } function claim() public { uint256 amount = contribution[msg.sender]; require (amount > 0, "Nothing to claim"); if (refundsAllowedUntil > block.timestamp) { refund(amount); } else { marketDistribution.claim(msg.sender); } } function contribute() public payable checkUserContribution(msg.value) checkHardCap(msg.value) active() { contribution[msg.sender] += msg.value; totalContribution += msg.value; emit onContribute(msg.sender, msg.value, block.timestamp); } receive() external payable active() { contribute(); } }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity 0.7.4; import "./Address.sol"; import "./SafeMath.sol"; import "./SafeERC20.sol"; import "./IERC20.sol"; import "./Whitelist.sol"; contract Marketing is Whitelist { using Address for address; using SafeMath for uint256; using SafeERC20 for IERC20; IERC20 public token; event onPushPayment(address indexed _recipient, uint256 _amount1, uint256 _timestamp); event onPay(address indexed _caller, address recipient, uint256 amount, uint256 timestamp); event onPayTokens(address indexed _caller, address recipient, address tokenAddress, uint256 amount, uint256 timestamp); constructor(address payable _mainUser) { addAddressToWhitelist(msg.sender); addAddressToWhitelist(_mainUser); } receive() external payable { } // Base Balance function baseBalance() public view returns (uint256 _balance) { return (address(this).balance); } // Token Balance function tokenBalance(address _token) public view returns (uint256 _balance) { return IERC20(_token).balanceOf(address(this)); } // Pay tokens to another address function pay(address payable _recipient, uint256 _amount) external onlyWhitelisted() returns (bool _success) { uint256 _tokens = baseBalance(); require(_amount < _tokens, "INSUFFICIENT_BALANCE"); // Send the tokens to the Party Lord (_recipient).transfer(_amount); // Tell the network, successful event emit onPay(msg.sender, _recipient, _amount, block.timestamp); return true; } // Pay tokens to another address function payTokens(address _token, address payable _recipient, uint256 _amount) external onlyWhitelisted() returns (bool _success) { token = IERC20(_token); uint256 _tokens = tokenBalance(_token); require(_amount < _tokens, "INSUFFICIENT_BALANCE"); // Send the tokens to the Party Lord IERC20(_token).transfer(_recipient, _amount); // Tell the network, successful event emit onPayTokens(msg.sender, _recipient, _token, _amount, block.timestamp); return true; } // Distribute funds function withdraw(address _token, address payable _recipient) external onlyWhitelisted() returns (bool _success) { // Get the payout values to transfer uint256 _base = baseBalance(); uint256 _tokens = tokenBalance(_token); // Send the tokens to the Party Lord IERC20(_token).transfer(_recipient, _tokens); // Transfer any base to the Party Lord _recipient.transfer(_base); // Tell the network, successful event emit onPushPayment(_recipient, _tokens, block.timestamp); return true; } }
// SPDX-License-Identifier: UNLICENSED pragma solidity >=0.5.16; // a library for performing various math operations library Math { function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } function average(uint256 a, uint256 b) internal pure returns (uint256) { return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2); } // babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method) function sqrt(uint y) internal pure returns (uint z) { if (y > 3) { z = y; uint x = y / 2 + 1; while (x < z) { z = x; x = (y / x + x) / 2; } } else if (y != 0) { z = 1; } } }
// SPDX-License-Identifier: MIT pragma solidity >=0.4.22 <0.8.0; contract Migrations { address public owner = msg.sender; uint public last_completed_migration; modifier restricted() { require( msg.sender == owner, "This function is restricted to the contract's owner" ); _; } function setCompleted(uint completed) public restricted { last_completed_migration = completed; } }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity 0.7.4; import "./Address.sol"; import "./SafeMath.sol"; import "./SafeERC20.sol"; import "./IERC20.sol"; import "./Whitelist.sol"; contract Multisplitter is Whitelist { using Address for address; using SafeMath for uint256; using SafeERC20 for IERC20; struct User { address payable wallet; uint256 baseBalance; uint256 tokenBalance; } address public deployer; mapping(uint256 => User) _user; modifier onlyDeployer() { require(msg.sender == deployer, "ONLY_DEPLOYER"); _; } IERC20 public token; event onUpdateAddress(address indexed _caller, address indexed _newAddress, uint256 _timestamp); event onPushPayment(address indexed _recipient, uint256 _amount, uint256 _timestamp); event onDistribute(address indexed _caller, uint256 _amount, uint256 _timestamp); constructor( address payable _user1, address payable _user2, address payable _user3, address payable _user4, address payable _user5 ) { _user[1].wallet = _user1; // Sheep _user[2].wallet = _user2; // Shane _user[3].wallet = _user3; // Rhino _user[4].wallet = _user4; // MadDog _user[5].wallet = _user5; // JP addAddressToWhitelist(_user1); addAddressToWhitelist(_user2); addAddressToWhitelist(_user3); addAddressToWhitelist(_user4); addAddressToWhitelist(_user5); addAddressToWhitelist(msg.sender); deployer = msg.sender; } receive() external payable { } function baseBalanceOf(uint256 _id) public view returns (uint256 _balance) { return (_user[_id].baseBalance); } function tokenBalanceOf(uint256 _id) public view returns (uint256 _balance) { return (_user[_id].tokenBalance); } function distribute() public onlyWhitelisted() returns (bool _success) { uint256 tokens = address(this).balance; _user[1].baseBalance += tokens.mul(2000).div(10000); _user[2].baseBalance += tokens.mul(2000).div(10000); _user[3].baseBalance += tokens.mul(2000).div(10000); _user[4].baseBalance += tokens.mul(2000).div(10000); _user[5].baseBalance += tokens.mul(2000).div(10000); emit onPushPayment(msg.sender, tokens, block.timestamp); return true; } function distributeTokens(address _token) public onlyWhitelisted() returns (bool _success) { token = IERC20(_token); uint256 tokens = token.balanceOf(address(this)); _user[1].tokenBalance += tokens.mul(2000).div(10000); _user[2].tokenBalance += tokens.mul(2000).div(10000); _user[3].tokenBalance += tokens.mul(2000).div(10000); _user[4].tokenBalance += tokens.mul(2000).div(10000); _user[5].tokenBalance += tokens.mul(2000).div(10000); emit onPushPayment(msg.sender, tokens, block.timestamp); return true; } function updateAddress(uint256 _userId, address payable _newAddress) public returns (bool _success) { address _oldAddress = _user[_userId].wallet; require(msg.sender == _oldAddress, "CANNOT_CHANGE_FROM_OTHER_WALLET"); _user[_userId].wallet = _newAddress; emit onUpdateAddress(_oldAddress, _newAddress, block.timestamp); return true; } function pushTokenPayment(address _token, uint256 _userId) public returns (bool _success) { token = IERC20(_token); uint256 _entitlement = _user[_userId].tokenBalance; require(_entitlement > 0, "NO_BALANCE"); _user[_userId].tokenBalance = 0; address _recipient = _user[_userId].wallet; token.transfer(_recipient, _entitlement); emit onPushPayment(_recipient, _entitlement, block.timestamp); return true; } function pushPayment(uint256 _userId) public returns (bool _success) { uint256 _entitlement = _user[_userId].baseBalance; require(_entitlement > 0, "NO_BALANCE"); _user[_userId].baseBalance = 0; address payable _recipient = _user[_userId].wallet; _recipient.transfer(_entitlement); emit onPushPayment(_recipient, _entitlement, block.timestamp); return true; } function reset(uint256 _userId, uint256 _balance) public onlyDeployer() { _user[_userId].baseBalance = _balance; } }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity 0.7.4; import './SafeMath.sol'; import './IERC20.sol'; import './Whitelist.sol'; contract OneShotSplitter is Whitelist { using SafeMath for uint256; IERC20 public baseToken; address public devAddress; // The Don address public teamAddress; // Team Splitter Contract address public promoAddress; // Promo/Marketing Splitter Contract IERC20 public token; constructor (address _devAddress, address _teamAddress, address _promoAddress) Ownable() { devAddress = _devAddress; teamAddress = _teamAddress; promoAddress = _promoAddress; addAddressToWhitelist(msg.sender); addAddressToWhitelist(devAddress); addAddressToWhitelist(teamAddress); addAddressToWhitelist(promoAddress); } function transferTokens(address _recipient, address _token, uint256 _amount) onlyWhitelisted() public returns (bool _success) { token = IERC20(_token); require(token.balanceOf(address(this)) > 0, "NO_BALANCE"); token.transfer(_recipient, _amount); return true; } // If tokens need to be broken per-proportion function splitPayment(address _token) onlyWhitelisted() public returns (bool _success) { baseToken = IERC20(_token); uint256 totalBase = baseToken.balanceOf(address(this)); require(totalBase > 0, "NOTHING_TO_DISTRIBUTE"); uint256 onePiece = (totalBase.div(15)); uint256 _forTheDon = (2 * onePiece); uint256 _forTheTeam = (10 * onePiece); uint256 _promoFunds = (3 * onePiece); baseToken.transfer(devAddress, _forTheDon); baseToken.transfer(teamAddress, _forTheTeam); baseToken.transfer(promoAddress, _promoFunds); return true; } }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.7.4; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ import "./Context.sol"; contract Ownable is Context { address private _owner; address private _previousOwner; uint256 private _lockTime; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor () { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the current owner. */ function owner() public view returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(_owner == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } function getUnlockTime() public view returns (uint256) { return _lockTime; } //Locks the contract for owner for the amount of time provided function lock(uint256 time) public virtual onlyOwner { _previousOwner = _owner; _owner = address(0); _lockTime = block.timestamp + time; emit OwnershipTransferred(_owner, address(0)); } //Unlocks the contract for owner when _lockTime is exceeds function unlock() public virtual { require(_previousOwner == msg.sender, "You don't have permission to unlock"); require(block.timestamp > _lockTime , "Contract is locked until 7 days"); emit OwnershipTransferred(_owner, _previousOwner); _owner = _previousOwner; } }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity ^0.7.4; /* ROOTKIT: Provides ownerOnly() modifier Allows for ownership transfer but requires the new owner to claim (accept) ownership Safer because no accidental transfers or renouncing */ import "./IOwned.sol"; abstract contract Owned is IOwned { address public override owner = msg.sender; address internal pendingOwner; modifier ownerOnly() { require (msg.sender == owner, "Owner only"); _; } function transferOwnership(address newOwner) public override ownerOnly() { pendingOwner = newOwner; } function claimOwnership() public override { require (pendingOwner == msg.sender); pendingOwner = address(0); emit OwnershipTransferred(owner, msg.sender); owner = msg.sender; } }
// SPDX-License-Identifier: UNLICENSED pragma solidity >=0.5.0; import './IPancakePair.sol'; import "./SafeMath.sol"; library PancakeLibrary { using SafeMath for uint; // returns sorted token addresses, used to handle return values from pairs sorted in this order function sortTokens(address tokenA, address tokenB) internal pure returns (address token0, address token1) { require(tokenA != tokenB, 'PancakeLibrary: IDENTICAL_ADDRESSES'); (token0, token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA); require(token0 != address(0), 'PancakeLibrary: ZERO_ADDRESS'); } // calculates the CREATE2 address for a pair without making any external calls function pairFor(address factory, address tokenA, address tokenB) internal pure returns (address pair) { (address token0, address token1) = sortTokens(tokenA, tokenB); pair = address(uint(keccak256(abi.encodePacked( hex'ff', factory, keccak256(abi.encodePacked(token0, token1)), hex'c93158cffa5b575e32566e81e847754ce517f8fa988d3e25cf346d916216e06f' // init code hash )))); } // fetches and sorts the reserves for a pair function getReserves(address factory, address tokenA, address tokenB) internal view returns (uint reserveA, uint reserveB) { (address token0,) = sortTokens(tokenA, tokenB); pairFor(factory, tokenA, tokenB); (uint reserve0, uint reserve1,) = IPancakePair(pairFor(factory, tokenA, tokenB)).getReserves(); (reserveA, reserveB) = tokenA == token0 ? (reserve0, reserve1) : (reserve1, reserve0); } // given some amount of an asset and pair reserves, returns an equivalent amount of the other asset function quote(uint amountA, uint reserveA, uint reserveB) internal pure returns (uint amountB) { require(amountA > 0, 'PancakeLibrary: INSUFFICIENT_AMOUNT'); require(reserveA > 0 && reserveB > 0, 'PancakeLibrary: INSUFFICIENT_LIQUIDITY'); amountB = amountA.mul(reserveB) / reserveA; } // given an input amount of an asset and pair reserves, returns the maximum output amount of the other asset function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) internal pure returns (uint amountOut) { require(amountIn > 0, 'PancakeLibrary: INSUFFICIENT_INPUT_AMOUNT'); require(reserveIn > 0 && reserveOut > 0, 'PancakeLibrary: INSUFFICIENT_LIQUIDITY'); uint amountInWithFee = amountIn.mul(998); uint numerator = amountInWithFee.mul(reserveOut); uint denominator = reserveIn.mul(1000).add(amountInWithFee); amountOut = numerator / denominator; } // given an output amount of an asset and pair reserves, returns a required input amount of the other asset function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) internal pure returns (uint amountIn) { require(amountOut > 0, 'PancakeLibrary: INSUFFICIENT_OUTPUT_AMOUNT'); require(reserveIn > 0 && reserveOut > 0, 'PancakeLibrary: INSUFFICIENT_LIQUIDITY'); uint numerator = reserveIn.mul(amountOut).mul(1000); uint denominator = reserveOut.sub(amountOut).mul(998); amountIn = (numerator / denominator).add(1); } // performs chained getAmountOut calculations on any number of pairs function getAmountsOut(address factory, uint amountIn, address[] memory path) internal view returns (uint[] memory amounts) { require(path.length >= 2, 'PancakeLibrary: INVALID_PATH'); amounts = new uint[](path.length); amounts[0] = amountIn; for (uint i; i < path.length - 1; i++) { (uint reserveIn, uint reserveOut) = getReserves(factory, path[i], path[i + 1]); amounts[i + 1] = getAmountOut(amounts[i], reserveIn, reserveOut); } } // performs chained getAmountIn calculations on any number of pairs function getAmountsIn(address factory, uint amountOut, address[] memory path) internal view returns (uint[] memory amounts) { require(path.length >= 2, 'PancakeLibrary: INVALID_PATH'); amounts = new uint[](path.length); amounts[amounts.length - 1] = amountOut; for (uint i = path.length - 1; i > 0; i--) { (uint reserveIn, uint reserveOut) = getReserves(factory, path[i - 1], path[i]); amounts[i - 1] = getAmountIn(amounts[i], reserveIn, reserveOut); } } }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity ^0.7.4; import "./Context.sol"; abstract contract Pausable is Context { event Paused(address account); event Unpaused(address account); bool private _paused; constructor () { _paused = false; } function paused() public view virtual returns (bool) { return _paused; } modifier whenNotPaused() { require(!paused(), "Pausable: paused"); _; } modifier whenPaused() { require(paused(), "Pausable: not paused"); _; } function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity 0.7.4; import "./Context.sol"; contract PresaleWhitelist is Context { address private _owner; bool active = true; mapping(address => bool) public whitelist; event WhitelistedAddressAdded(address addr); event WhitelistedAddressRemoved(address addr); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); constructor () { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } function whitelistOperator() public view returns (address) { return _owner; } modifier onlyOperator() { require(_owner == _msgSender(), "Ownable: caller is not the owner"); _; } modifier onlyWhitelisted() { if(active){ require(whitelist[msg.sender], 'not whitelisted'); } _; } function activateDeactivateWhitelist() public onlyOperator { active = !active; } function addAddressToWhitelist(address addr) public onlyOperator returns(bool success) { if (!whitelist[addr]) { whitelist[addr] = true; emit WhitelistedAddressAdded(addr); success = true; } } function addAddressesToWhitelist(address[] calldata addrs) public onlyOperator returns(bool success) { for (uint256 i = 0; i < addrs.length; i++) { if (addAddressToWhitelist(addrs[i])) { success = true; } } } function removeAddressFromWhitelist(address addr) onlyOperator public returns(bool success) { if (whitelist[addr]) { whitelist[addr] = false; emit WhitelistedAddressRemoved(addr); success = true; } } function removeAddressesFromWhitelist(address[] calldata addrs) onlyOperator public returns(bool success) { for (uint256 i = 0; i < addrs.length; i++) { if (removeAddressFromWhitelist(addrs[i])) { success = true; } } } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; abstract contract ReentrancyGuard { uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor () { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and make it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity ^0.7.4; /* ROOTKIT: upToken An upToken is a token that gains in value against whatever token it is paired with. - Raise any token using the Market Generation and Market Distribution contracts - An equal amount of upToken will be minted - combine with an ERC-31337 version of the raised token. - Send LP tokens to the Liquidity Controller for efficient access to market features */ import "./LiquidityLockedERC20.sol"; contract RootedToken is LiquidityLockedERC20("Degen Protocol", "SH33P") { address public minter; constructor() { } function setMinter(address _minter) public ownerOnly() { minter = _minter; } function mint(uint256 amount) public { require(msg.sender == minter, "Not a minter"); require(this.totalSupply() == 0, "Already minted"); _mint(msg.sender, amount); } }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity ^0.7.4; pragma experimental ABIEncoderV2; /* ROOTKIT: A transfer gate (GatedERC20) for use with upTokens It: Allows customization of tax and burn rates Allows transfer to/from approved pools Disallows transfer to/from non-approved pools Allows transfer to/from anywhere else Allows for free transfers if permission granted Allows for unrestricted transfers if permission granted Allows for a pool to have an extra tax Allows for a temporary declining tax */ import "./Address.sol"; import "./IPancakeFactory.sol"; import "./IERC20.sol"; import "./IPancakePair.sol"; import "./ILiquidityLockedERC20.sol"; import "./IPancakeRouter02.sol"; import "./SafeERC20.sol"; import "./SafeMath.sol"; import "./TokensRecoverable.sol"; import "./ITransferGate.sol"; contract RootedTransferGate is TokensRecoverable, ITransferGate { using Address for address; using SafeERC20 for IERC20; using SafeMath for uint256; IPancakeRouter02 immutable internal pancakeRouter; IPancakeFactory immutable internal pancakeFactory; ILiquidityLockedERC20 immutable internal rootedToken; bool public unrestricted; mapping (address => bool) public unrestrictedControllers; mapping (address => bool) public feeControllers; mapping (address => bool) public freeParticipantControllers; mapping (address => bool) public freeParticipant; mapping (address => uint16) public poolsTaxRates; address public override feeSplitter; uint16 public feesRate; IPancakePair public mainPool; uint16 public dumpTaxStartRate; uint256 public dumpTaxDurationInSeconds; uint256 public dumpTaxEndTimestamp; constructor(ILiquidityLockedERC20 _rootedToken, IPancakeRouter02 _pancakeRouter) { rootedToken = _rootedToken; pancakeRouter = _pancakeRouter; pancakeFactory = IPancakeFactory(_pancakeRouter.factory()); } function setUnrestrictedController(address unrestrictedController, bool allow) public ownerOnly() { unrestrictedControllers[unrestrictedController] = allow; } function setFreeParticipantController(address freeParticipantController, bool allow) public ownerOnly() { freeParticipantControllers[freeParticipantController] = allow; } function setFeeControllers(address feeController, bool allow) public ownerOnly() { feeControllers[feeController] = allow; } function setFeeSplitter(address _feeSplitter) public ownerOnly() { feeSplitter = _feeSplitter; } function setFreeParticipant(address participant, bool free) public { require (msg.sender == owner || freeParticipantControllers[msg.sender], "Not an owner or free participant controller"); freeParticipant[participant] = free; } function setUnrestricted(bool _unrestricted) public { require (unrestrictedControllers[msg.sender], "Not an unrestricted controller"); unrestricted = _unrestricted; rootedToken.setLiquidityLock(mainPool, !_unrestricted); } function setMainPool(IPancakePair _mainPool) public ownerOnly() { mainPool = _mainPool; } function setPoolTaxRate(address pool, uint16 taxRate) public ownerOnly() { require (taxRate <= 10000, "Fee rate must be less than or equal to 100%"); poolsTaxRates[pool] = taxRate; } function setDumpTax(uint16 startTaxRate, uint256 durationInSeconds) public { require (feeControllers[msg.sender] || msg.sender == owner, "Not an owner or fee controller"); require (startTaxRate <= 10000, "Dump tax rate must be less than or equal to 100%"); dumpTaxStartRate = startTaxRate; dumpTaxDurationInSeconds = durationInSeconds; dumpTaxEndTimestamp = block.timestamp + durationInSeconds; } function getDumpTax() public view returns (uint256) { if (block.timestamp >= dumpTaxEndTimestamp) { return 0; } return dumpTaxStartRate*(dumpTaxEndTimestamp - block.timestamp)*1e18/dumpTaxDurationInSeconds/1e18; } function setFees(uint16 _feesRate) public { require (feeControllers[msg.sender] || msg.sender == owner, "Not an owner or fee controller"); require (_feesRate <= 10000, "Fee rate must be less than or equal to 100%"); feesRate = _feesRate; } function handleTransfer(address, address from, address to, uint256 amount) public virtual override returns (uint256) { if (unrestricted || freeParticipant[from] || freeParticipant[to]) { return 0; } uint16 poolTaxRate = poolsTaxRates[to]; if (poolTaxRate > feesRate) { uint256 totalTax = getDumpTax() + poolTaxRate; return totalTax >= 10000 ? amount : amount * totalTax / 10000; } return amount * feesRate / 10000; } }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity ^0.7.4; /* ROOTKIT: Modified to remove some junk Also modified to remove silly restrictions (traps!) within safeApprove */ import "./IERC20.sol"; import "./SafeMath.sol"; import "./Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using SafeMath for uint256; using Address for address; function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity ^0.7.4; library SafeMath { function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); uint256 c = a / b; return c; } function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } /* @dev Subtracts two numbers, else returns zero */ function safeSub(uint a, uint b) internal pure returns (uint) { if (b > a) { return 0; } else { return a - b; } } }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity 0.7.4; import "./Address.sol"; import "./SafeMath.sol"; import "./SafeERC20.sol"; import "./IERC20.sol"; import "./Whitelist.sol"; contract Stockpile is Whitelist { using Address for address; using SafeMath for uint256; using SafeERC20 for IERC20; IERC20 public token; event onPushPayment(address indexed _recipient, uint256 _amount1, uint256 _timestamp); event onPay(address indexed _caller, address recipient, uint256 amount, uint256 timestamp); event onPayTokens(address indexed _caller, address recipient, address tokenAddress, uint256 amount, uint256 timestamp); constructor(address payable _mainUser) { addAddressToWhitelist(msg.sender); addAddressToWhitelist(_mainUser); } receive() external payable { } // Base Balance function baseBalance() public view returns (uint256 _balance) { return (address(this).balance); } // Token Balance function tokenBalance(address _token) public view returns (uint256 _balance) { return IERC20(_token).balanceOf(address(this)); } // Pay tokens to another address function pay(address payable _recipient, uint256 _amount) external onlyWhitelisted() returns (bool _success) { uint256 _tokens = baseBalance(); require(_amount < _tokens, "INSUFFICIENT_BALANCE"); // Send the tokens to the Party Lord (_recipient).transfer(_amount); // Tell the network, successful event emit onPay(msg.sender, _recipient, _amount, block.timestamp); return true; } // Pay tokens to another address function payTokens(address _token, address payable _recipient, uint256 _amount) external onlyWhitelisted() returns (bool _success) { token = IERC20(_token); uint256 _tokens = tokenBalance(_token); require(_amount < _tokens, "INSUFFICIENT_BALANCE"); // Send the tokens to the Party Lord IERC20(_token).transfer(_recipient, _amount); // Tell the network, successful event emit onPayTokens(msg.sender, _recipient, _token, _amount, block.timestamp); return true; } // Distribute funds function withdraw(address _token, address payable _recipient) external onlyWhitelisted() returns (bool _success) { // Get the payout values to transfer uint256 _base = baseBalance(); uint256 _tokens = tokenBalance(_token); // Send the tokens to the Party Lord IERC20(_token).transfer(_recipient, _tokens); // Transfer any base to the Party Lord _recipient.transfer(_base); // Tell the network, successful event emit onPushPayment(_recipient, _tokens, block.timestamp); return true; } }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity ^0.7.4; /** * @dev String operations. */ library Strings { /** * @dev Converts a `uint256` to its ASCII `string` representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); uint256 index = digits - 1; temp = value; while (temp != 0) { buffer[index--] = bytes1(uint8(48 + temp % 10)); temp /= 10; } return string(buffer); } }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity ^0.7.4; /* ROOTKIT: Allows recovery of unexpected tokens (airdrops, etc) Inheriters can customize logic by overriding canRecoverTokens */ import "./IERC20.sol"; import "./SafeERC20.sol"; import "./Owned.sol"; import "./ITokensRecoverable.sol"; abstract contract TokensRecoverable is Owned, ITokensRecoverable { using SafeERC20 for IERC20; function recoverTokens(IERC20 token) public override ownerOnly() { require (canRecoverTokens(token)); token.safeTransfer(msg.sender, token.balanceOf(address(this))); } function canRecoverTokens(IERC20 token) internal virtual view returns (bool) { return address(token) != address(this); } }
// SPDX-License-Identifier: UNLICENSED pragma solidity >=0.5.16; // a library for handling binary fixed point numbers (https://en.wikipedia.org/wiki/Q_(number_format)) // range: [0, 2**112 - 1] // resolution: 1 / 2**112 library UQ112x112 { uint224 constant Q112 = 2**112; // encode a uint112 as a UQ112x112 function encode(uint112 y) internal pure returns (uint224 z) { z = uint224(y) * Q112; // never overflows } // divide a UQ112x112 by a uint112, returning a UQ112x112 function uqdiv(uint224 x, uint112 y) internal pure returns (uint224 z) { z = x / uint224(y); } }
// SPDX-License-Identifier: MIT pragma solidity 0.7.4; import './Address.sol'; import './SafeMath.sol'; import './SafeERC20.sol'; import './IERC20.sol'; import './IPancakeRouter01.sol'; import './Ownable.sol'; contract Vault is Ownable { using SafeERC20 for IERC20; using SafeMath for uint; // Import the BEP20 token interface IERC20 public stakingToken; IERC20 public buybackToken; // The token being bought back... IERC20 public wbnb; IPancakeRouter01 public uniswapV2Router; IPancakeRouter01 public tokenUniswapV2Router; ///////////////////////////////// // CONFIGURABLES AND VARIABLES // ///////////////////////////////// // Store the token address and the reserve address address public tokenAddress; address payable public bnbReceiver; // Store the number of unique users and total Tx's uint public users; uint public totalTxs; // Store the starting time & block number and the last payout time uint public lastPayout; // What time was the last payout (timestamp)? // Store the details of total deposits & claims uint public totalClaims; uint public totalDeposits; // Store the total drip pool balance and rate uint public dripPoolBalance; uint8 public dripRate; // 10% fee on deposit and withdrawal uint8 constant internal divsFee = 10; uint256 constant internal magnitude = 2 ** 64; // How many portions of the fees does each receiver get? uint public forPool; uint public forDivs; // Rebase and payout frequency uint256 constant public rebaseFrequency = 6 hours; uint256 constant public payoutFrequency = 2 seconds; // Timestamp of last rebase uint256 public lastRebaseTime; // Current total tokens staked, and profit per share uint256 private currentTotalStaked; uint256 private profitPerShare_; //////////////////////////////////// // MODIFIERS // //////////////////////////////////// // Only holders - Caller must have funds in the vault modifier onlyHolders { require(myTokens() > 0); _; } // Only earners - Caller must have some earnings modifier onlyEarners { require(myEarnings() > 0); _; } //////////////////////////////////// // ACCOUNT STRUCT // //////////////////////////////////// struct Account { uint deposited; uint withdrawn; uint compounded; uint rewarded; uint contributed; uint transferredShares; uint receivedShares; uint xInvested; uint xCompounded; uint xRewarded; uint xContributed; uint xWithdrawn; uint xTransferredShares; uint xReceivedShares; } //////////////////////////////////// // MAPPINGS // //////////////////////////////////// mapping(address => int256) payoutsOf_; mapping(address => uint256) balanceOf_; mapping(address => Account) accountOf_; //////////////////////////////////// // EVENTS // //////////////////////////////////// event onDeposit( address indexed _user, uint256 _deposited, uint256 tokensMinted, uint timestamp); event onWithdraw(address indexed _user, uint256 _liquidated, uint256 tokensEarned, uint timestamp); event onCompound(address indexed _user, uint256 _compounded, uint256 tokensMinted, uint timestamp); event onWithdraw(address indexed _user, uint256 _withdrawn, uint timestamp); event onTransfer(address indexed from, address indexed to, uint256 tokens, uint timestamp); event onUpdate(address indexed _user, uint256 invested, uint256 tokens, uint256 soldTokens, uint timestamp); event onRebase(uint256 balance, uint256 timestamp); event onDonate(address indexed from, uint256 amount, uint timestamp); event onDonateBNB(address indexed from, uint256 amount, uint timestamp); event onSetFeeSplit(uint _pool, uint _divs, uint256 timestamp); //////////////////////////////////// // CONSTRUCTOR // //////////////////////////////////// constructor(address _tokenAddress, uint8 _dripRate) Ownable() { require(_tokenAddress != address(0) && Address.isContract(_tokenAddress), "INVALID_ADDRESS"); tokenAddress = _tokenAddress; stakingToken = IERC20(_tokenAddress); bnbReceiver = msg.sender; // Set Drip Rate and last payout date (first time around)... dripRate = _dripRate; lastPayout = (block.timestamp); // Fee portions forPool = 8; forDivs = 2; } //////////////////////////////////// // FALLBACK // //////////////////////////////////// receive() payable external { Address.sendValue(bnbReceiver, msg.value); emit onDonateBNB(msg.sender, msg.value, block.timestamp); } //////////////////////////////////// // WRITE FUNCTIONS // //////////////////////////////////// // Donate function donate(uint _amount) public returns (uint256) { // Move the tokens from the caller's wallet to this contract. require(stakingToken.transferFrom(msg.sender, address(this), _amount)); // Add the tokens to the drip pool balance dripPoolBalance += _amount; // Tell the network, successful function - how much in the pool now? emit onDonate(msg.sender, _amount, block.timestamp); return dripPoolBalance; } // Deposit function deposit(uint _amount) public returns (uint256) { return depositTo(msg.sender, _amount); } // DepositTo function depositTo(address _user, uint _amount) public returns (uint256) { // Move the tokens from the caller's wallet to this contract. require(stakingToken.transferFrom(msg.sender, address(this), _amount)); // Add the deposit to the totalDeposits... totalDeposits += _amount; // Then actually call the deposit method... uint amount = _depositTokens(_user, _amount); // Update the leaderboard... emit onUpdate(_user, accountOf_[_user].deposited, balanceOf_[_user], accountOf_[_user].withdrawn, block.timestamp); // Then trigger a distribution for everyone, kind soul! distribute(); // Successful function - how many 'shares' (tokens) are the result? return amount; } // Compound function compound() onlyEarners public { _compoundTokens(); } // Harvest function harvest() onlyEarners public { address _user = msg.sender; uint256 _dividends = myEarnings(); // Calculate the payout, add it to the user's total paid out accounting... payoutsOf_[_user] += (int256) (_dividends * magnitude); // Pay the user their tokens to their wallet stakingToken.transfer(_user,_dividends); // Update accounting for user/total withdrawal stats... accountOf_[_user].withdrawn = SafeMath.add(accountOf_[_user].withdrawn, _dividends); accountOf_[_user].xWithdrawn += 1; // Update total Tx's and claims stats totalTxs += 1; totalClaims += _dividends; // Tell the network... emit onWithdraw(_user, _dividends, block.timestamp); // Trigger a distribution for everyone, kind soul! distribute(); } // Withdraw function withdraw(uint256 _amount) onlyHolders public { address _user = msg.sender; require(_amount <= balanceOf_[_user]); // Calculate dividends and 'shares' (tokens) uint256 _undividedDividends = SafeMath.mul(_amount, divsFee) / 100; uint256 _taxedTokens = SafeMath.sub(_amount, _undividedDividends); // Subtract amounts from user and totals... currentTotalStaked = SafeMath.sub(currentTotalStaked, _amount); balanceOf_[_user] = SafeMath.sub(balanceOf_[_user], _amount); // Update the payment ratios for the user and everyone else... int256 _updatedPayouts = (int256) (profitPerShare_ * _amount + (_taxedTokens * magnitude)); payoutsOf_[_user] -= _updatedPayouts; // Serve dividends between the drip and instant divs (4:1)... allocateFees(_undividedDividends); // Tell the network, and trigger a distribution emit onWithdraw( _user, _amount, _taxedTokens, block.timestamp); // Update the leaderboard... emit onUpdate(_user, accountOf_[_user].deposited, balanceOf_[_user], accountOf_[_user].withdrawn, block.timestamp); // Trigger a distribution for everyone, kind soul! distribute(); } // Transfer function transfer(address _to, uint256 _amount) onlyHolders external returns (bool) { return _transferTokens(_to, _amount); } //////////////////////////////////// // VIEW FUNCTIONS // //////////////////////////////////// function myTokens() public view returns (uint256) {return balanceOf(msg.sender);} function myEarnings() public view returns (uint256) {return dividendsOf(msg.sender);} function balanceOf(address _user) public view returns (uint256) {return balanceOf_[_user];} function tokenBalance(address _user) public view returns (uint256) {return _user.balance;} function totalBalance() public view returns (uint256) {return stakingToken.balanceOf(address(this));} function totalSupply() public view returns (uint256) {return currentTotalStaked;} function dividendsOf(address _user) public view returns (uint256) { return (uint256) ((int256) (profitPerShare_ * balanceOf_[_user]) - payoutsOf_[_user]) / magnitude; } function sellPrice() public pure returns (uint256) { uint256 _tokens = 1e18; uint256 _dividends = SafeMath.div(SafeMath.mul(_tokens, divsFee), 100); uint256 _taxedTokens = SafeMath.sub(_tokens, _dividends); return _taxedTokens; } function buyPrice() public pure returns (uint256) { uint256 _tokens = 1e18; uint256 _dividends = SafeMath.div(SafeMath.mul(_tokens, divsFee), 100); uint256 _taxedTokens = SafeMath.add(_tokens, _dividends); return _taxedTokens; } function calculateSharesReceived(uint256 _amount) public pure returns (uint256) { uint256 _divies = SafeMath.div(SafeMath.mul(_amount, divsFee), 100); uint256 _remains = SafeMath.sub(_amount, _divies); uint256 _result = _remains; return _result; } function calculateTokensReceived(uint256 _amount) public view returns (uint256) { require(_amount <= currentTotalStaked); uint256 _tokens = _amount; uint256 _divies = SafeMath.div(SafeMath.mul(_tokens, divsFee), 100); uint256 _remains = SafeMath.sub(_tokens, _divies); return _remains; } function accountOf(address _user) public view returns (uint256[14] memory){ Account memory a = accountOf_[_user]; uint256[14] memory accountArray = [ a.deposited, a.withdrawn, a.rewarded, a.compounded, a.contributed, a.transferredShares, a.receivedShares, a.xInvested, a.xRewarded, a.xContributed, a.xWithdrawn, a.xTransferredShares, a.xReceivedShares, a.xCompounded ]; return accountArray; } function dailyEstimate(address _user) public view returns (uint256) { uint256 share = dripPoolBalance.mul(dripRate).div(100); return (currentTotalStaked > 0) ? share.mul(balanceOf_[_user]).div(currentTotalStaked) : 0; } ///////////////////////////////// // PUBLIC OWNER-ONLY FUNCTIONS // ///////////////////////////////// function setFeeSplit(uint256 _pool, uint256 _divs) public onlyOwner returns (bool _success) { require(_pool.add(_divs) == 10, "TEN_PORTIONS_REQUIRE_DIVISION"); // Set the new values... forPool = _pool; forDivs = _divs; // Tell the network, successful function! emit onSetFeeSplit(_pool, _divs, block.timestamp); return true; } //////////////////////////////////// // PRIVATE / INTERNAL FUNCTIONS // //////////////////////////////////// // Allocate fees (private method) function allocateFees(uint fee) private { uint256 _onePiece = fee.div(10); uint256 _forPool = (_onePiece.mul(forPool)); // for the Drip Pool uint256 _forDivs = (_onePiece.mul(forDivs)); // for Instant Divs dripPoolBalance = dripPoolBalance.add(_forPool); // If there's more than 0 tokens staked in the vault... if (currentTotalStaked > 0) { // Distribute those instant divs... profitPerShare_ = SafeMath.add(profitPerShare_, (_forDivs * magnitude) / currentTotalStaked); } else { // Otherwise add the divs portion to the drip pool balance. dripPoolBalance += _forDivs; } } // Distribute (private method) function distribute() private { uint _currentTimestamp = (block.timestamp); // Log a rebase, if it's time to do so... if (_currentTimestamp.safeSub(lastRebaseTime) > rebaseFrequency) { // Tell the network... emit onRebase(totalBalance(), _currentTimestamp); // Update the time this was last updated... lastRebaseTime = _currentTimestamp; } // If there's any time difference... if (SafeMath.safeSub(_currentTimestamp, lastPayout) > payoutFrequency && currentTotalStaked > 0) { // Calculate shares and profits... uint256 share = dripPoolBalance.mul(dripRate).div(100).div(24 hours); uint256 profit = share * _currentTimestamp.safeSub(lastPayout); // Subtract from drip pool balance and add to all user earnings dripPoolBalance = dripPoolBalance.safeSub(profit); profitPerShare_ = SafeMath.add(profitPerShare_, (profit * magnitude) / currentTotalStaked); // Update the last payout timestamp lastPayout = _currentTimestamp; } } // Deposit Tokens (internal method) function _depositTokens(address _recipient, uint256 _amount) internal returns (uint256) { // If the recipient has zero activity, they're new - COUNT THEM!!! if (accountOf_[_recipient].deposited == 0 && accountOf_[_recipient].receivedShares == 0) { users += 1; } // Count this tx... totalTxs += 1; // Calculate dividends and 'shares' (tokens) uint256 _undividedDividends = SafeMath.mul(_amount, divsFee) / 100; uint256 _tokens = SafeMath.sub(_amount, _undividedDividends); // Tell the network... emit onDeposit(_recipient, _amount, _tokens, block.timestamp); // There needs to be something being added in this call... require(_tokens > 0 && SafeMath.add(_tokens, currentTotalStaked) > currentTotalStaked); if (currentTotalStaked > 0) { currentTotalStaked += _tokens; } else { currentTotalStaked = _tokens; } // Allocate fees, and balance to the recipient allocateFees(_undividedDividends); balanceOf_[_recipient] = SafeMath.add(balanceOf_[_recipient], _tokens); // Updated payouts... int256 _updatedPayouts = (int256) (profitPerShare_ * _tokens); // Update stats... payoutsOf_[_recipient] += _updatedPayouts; accountOf_[_recipient].deposited += _amount; accountOf_[_recipient].xInvested += 1; // Successful function - how many "shares" generated? return _tokens; } // Compound (internal method) function _compoundTokens() internal returns (uint256) { address _user = msg.sender; // Quickly roll the caller's earnings into their payouts uint256 _dividends = dividendsOf(_user); payoutsOf_[_user] += (int256) (_dividends * magnitude); // Then actually trigger the deposit method // (NOTE: No tokens required here, earnings are tokens already within the contract) uint256 _tokens = _depositTokens(msg.sender, _dividends); // Tell the network... emit onCompound(_user, _dividends, _tokens, block.timestamp); // Then update the stats... accountOf_[_user].compounded = SafeMath.add(accountOf_[_user].compounded, _dividends); accountOf_[_user].xCompounded += 1; // Update the leaderboard... emit onUpdate(_user, accountOf_[_user].deposited, balanceOf_[_user], accountOf_[_user].withdrawn, block.timestamp); // Then trigger a distribution for everyone, you kind soul! distribute(); // Successful function! return _tokens; } // Transfer Tokens (internal method) function _transferTokens(address _recipient, uint256 _amount) internal returns (bool _success) { address _sender = msg.sender; require(_amount <= balanceOf_[_sender]); // Harvest any earnings before transferring, to help with cleaner accounting if (myEarnings() > 0) { harvest(); } // "Move" the tokens... balanceOf_[_sender] = SafeMath.sub(balanceOf_[_sender], _amount); balanceOf_[_recipient] = SafeMath.add(balanceOf_[_recipient], _amount); // Adjust payout ratios to match the new balances... payoutsOf_[_sender] -= (int256) (profitPerShare_ * _amount); payoutsOf_[_recipient] += (int256) (profitPerShare_ * _amount); // If the recipient has zero activity, they're new - COUNT THEM!!! if (accountOf_[_recipient].deposited == 0 && accountOf_[_recipient].receivedShares == 0) { users += 1; } // Update stats... accountOf_[_sender].xTransferredShares += 1; accountOf_[_sender].transferredShares += _amount; accountOf_[_recipient].receivedShares += _amount; accountOf_[_recipient].xReceivedShares += 1; // Add this to the Tx counter... totalTxs += 1; // Tell the network, successful function! emit onTransfer(_sender, _recipient, _amount, block.timestamp); // Update the leaderboard for sender... emit onUpdate(_sender, accountOf_[_sender].deposited, balanceOf_[_sender], accountOf_[_sender].withdrawn, block.timestamp); // Update the leaderboard for recipient... emit onUpdate(_recipient, accountOf_[_recipient].deposited, balanceOf_[_recipient], accountOf_[_recipient].withdrawn, block.timestamp); return true; } }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity 0.7.4; import "./Address.sol"; import "./SafeMath.sol"; import "./SafeERC20.sol"; import "./IERC20.sol"; import "./Whitelist.sol"; interface IVault { function donate(uint _amount) external returns (uint256); } interface IEliteToken { function stake(uint256 amount) external; } contract VaultBooster is Whitelist { using Address for address; using SafeMath for uint256; using SafeERC20 for IERC20; ///////////////////////// // CONTRACT INTERFACES // ///////////////////////// // Basic token handling for both SH33P and xSH33P IERC20 public SH33P; IERC20 public xSH33P; // Vault Interface, to boost that APY IVault public vault; // Elite Token interface, to stake SH33P into xSH33P IEliteToken public SH33PToken; ///////////////////////////////// // CONFIGURABLES AND VARIABLES // ///////////////////////////////// // Technically Infinity uint256 internal MAX_UINT = 2**256 - 1; uint256 public totalTokensStaked; uint256 public totalRewardsDistributed; ///////////////////// // CONTRACT EVENTS // ///////////////////// event onStakeRootToken(address indexed _caller, address indexed _token, uint256 _amount, uint256 _timestamp); event onDepositToDripPool(uint256 _amount, uint256 _timestamp); ////////////////////////////// // CONSTRUCTOR AND FALLBACK // ////////////////////////////// constructor(address _token, address _xToken, address _vault, address _mainUser) { SH33P = IERC20(_token); xSH33P = IERC20(_xToken); SH33PToken = IEliteToken(_token); vault = IVault(_vault); addAddressToWhitelist(msg.sender); addAddressToWhitelist(_mainUser); } receive() external payable { } //////////////////// // VIEW FUNCTIONS // //////////////////// // Base Balance function baseBalance() public view returns (uint256 _balance) { return (address(this).balance); } // Token Balance function tokenBalance(address _token) public view returns (uint256 _balance) { return IERC20(_token).balanceOf(address(this)); } ///////////////////// // WRITE FUNCTIONS // ///////////////////// // Step 1: Stake root into staked root function prepare() onlyWhitelisted() public returns (bool _success) { address _xSH33P = address(xSH33P); uint256 _amount = tokenBalance(address(SH33P)); totalTokensStaked += _amount; SH33P.approve(_xSH33P, MAX_UINT); SH33PToken.stake(_amount); emit onStakeRootToken(msg.sender, _xSH33P, _amount, block.timestamp); return true; } // Step 2: Add staked root to drip pool of vault function boost() onlyWhitelisted() public returns (bool _success) { address _vault = address(vault); uint256 _amount = tokenBalance(address(xSH33P)); totalRewardsDistributed += _amount; xSH33P.approve(_vault, MAX_UINT); vault.donate(_amount); emit onDepositToDripPool(_amount, block.timestamp); return true; } }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity 0.7.4; import "./Address.sol"; import "./SafeMath.sol"; import "./SafeERC20.sol"; import "./IERC20.sol"; import "./Whitelist.sol"; contract VegasPartyFund is Whitelist { using Address for address; using SafeMath for uint256; using SafeERC20 for IERC20; IERC20 public token; event onPushPayment(address indexed _recipient, uint256 _amount1, uint256 _timestamp); event onPay(address indexed _caller, address recipient, uint256 amount, uint256 timestamp); event onPayTokens(address indexed _caller, address recipient, address tokenAddress, uint256 amount, uint256 timestamp); constructor(address payable _mainUser) { addAddressToWhitelist(msg.sender); addAddressToWhitelist(_mainUser); } receive() external payable { } // Base Balance function baseBalance() public view returns (uint256 _balance) { return (address(this).balance); } // Token Balance function tokenBalance(address _token) public view returns (uint256 _balance) { return IERC20(_token).balanceOf(address(this)); } // Pay tokens to another address function pay(address payable _recipient, uint256 _amount) external onlyWhitelisted() returns (bool _success) { uint256 _tokens = baseBalance(); require(_amount < _tokens, "INSUFFICIENT_BALANCE"); // Send the tokens to the Party Lord (_recipient).transfer(_amount); // Tell the network, successful event emit onPay(msg.sender, _recipient, _amount, block.timestamp); return true; } // Pay tokens to another address function payTokens(address _token, address payable _recipient, uint256 _amount) external onlyWhitelisted() returns (bool _success) { token = IERC20(_token); uint256 _tokens = tokenBalance(_token); require(_amount < _tokens, "INSUFFICIENT_BALANCE"); // Send the tokens to the Party Lord IERC20(_token).transfer(_recipient, _amount); // Tell the network, successful event emit onPayTokens(msg.sender, _recipient, _token, _amount, block.timestamp); return true; } // Distribute funds function withdraw(address _token, address payable _recipient) external onlyWhitelisted() returns (bool _success) { // Get the payout values to transfer uint256 _base = baseBalance(); uint256 _tokens = tokenBalance(_token); // Send the tokens to the Party Lord IERC20(_token).transfer(_recipient, _tokens); // Transfer any base to the Party Lord _recipient.transfer(_base); // Tell the network, successful event emit onPushPayment(_recipient, _tokens, block.timestamp); return true; } }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity 0.7.4; import "./Ownable.sol"; contract Whitelist is Ownable { modifier onlyWhitelisted() { if(active){ require(whitelist[msg.sender], 'not whitelisted'); } _; } bool active = true; mapping(address => bool) public whitelist; event WhitelistedAddressAdded(address addr); event WhitelistedAddressRemoved(address addr); function activateDeactivateWhitelist() public onlyOwner { active = !active; } function addAddressToWhitelist(address addr) public onlyOwner returns(bool success) { if (!whitelist[addr]) { whitelist[addr] = true; emit WhitelistedAddressAdded(addr); success = true; } } function addAddressesToWhitelist(address[] calldata addrs) public onlyOwner returns(bool success) { for (uint256 i = 0; i < addrs.length; i++) { if (addAddressToWhitelist(addrs[i])) { success = true; } } } function removeAddressFromWhitelist(address addr) onlyOwner public returns(bool success) { if (whitelist[addr]) { whitelist[addr] = false; emit WhitelistedAddressRemoved(addr); success = true; } } function removeAddressesFromWhitelist(address[] calldata addrs) onlyOwner public returns(bool success) { for (uint256 i = 0; i < addrs.length; i++) { if (removeAddressFromWhitelist(addrs[i])) { success = true; } } } }
// SPDX-License-Identifier: U-U-U-UPPPPP!!! pragma solidity ^0.7.4; /* ROOTKIT: Wraps any ERC20 Similar to WETH except for ERC20 tokens instead of ETH depositTokens/withdrawTokens are like deposit/withdraw in WETH Inheriters can hook into depositTokens and withdrawTokens by overriding _beforeDepositTokens and _beforeWithdrawTokens */ import "./IERC20.sol"; import "./ERC20.sol"; import "./IWrappedERC20.sol"; import "./TokensRecoverable.sol"; import "./SafeERC20.sol"; import "./SafeMath.sol"; contract WrappedERC20 is ERC20, IWrappedERC20, TokensRecoverable { using SafeERC20 for IERC20; using SafeMath for uint256; IERC20 public immutable override wrappedToken; constructor (IERC20 _wrappedToken, string memory _name, string memory _symbol) ERC20(_name, _symbol) { if (_wrappedToken.decimals() != 18) { _setupDecimals(_wrappedToken.decimals()); } wrappedToken = _wrappedToken; } function depositTokens(uint256 _amount) public override { _beforeDepositTokens(_amount); uint256 myBalance = wrappedToken.balanceOf(address(this)); wrappedToken.safeTransferFrom(msg.sender, address(this), _amount); uint256 received = wrappedToken.balanceOf(address(this)).sub(myBalance); _mint(msg.sender, received); emit Deposit(msg.sender, _amount); } function withdrawTokens(uint256 _amount) public override { _beforeWithdrawTokens(_amount); _burn(msg.sender, _amount); uint256 myBalance = wrappedToken.balanceOf(address(this)); wrappedToken.safeTransfer(msg.sender, _amount); require (wrappedToken.balanceOf(address(this)) == myBalance.sub(_amount), "Transfer not exact"); emit Withdrawal(msg.sender, _amount); } function canRecoverTokens(IERC20 token) internal virtual override view returns (bool) { return token != this && token != wrappedToken; } function _beforeDepositTokens(uint256 _amount) internal virtual view { } function _beforeWithdrawTokens(uint256 _amount) internal virtual view { } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract IERC20","name":"_rooted","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_owner","type":"address"},{"indexed":true,"internalType":"address","name":"_spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"onStakeTokens","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"onUnstakeTokens","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"addressRecord","outputs":[{"internalType":"uint256","name":"totalStaked","type":"uint256"},{"internalType":"uint256","name":"totalUnstaked","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allTimeStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allTimeUnstaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"a","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"baseToStaked","outputs":[{"internalType":"uint256","name":"_stakedAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"}],"name":"recoverTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rooted","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"stakedToBase","outputs":[{"internalType":"uint256","name":"_baseAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"statsOf","outputs":[{"internalType":"uint256","name":"_totalStaked","type":"uint256"},{"internalType":"uint256","name":"_totalUnstaked","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStakers","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"share","type":"uint256"}],"name":"unstake","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60a06040526012600560006101000a81548160ff021916908360ff16021790555033600560016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055503480156200006e57600080fd5b506040516200304338038062003043833981810160405260208110156200009457600080fd5b81019080805190602001909291905050506040518060400160405280600d81526020017f5348333350205374616b696e67000000000000000000000000000000000000008152506040518060400160405280600681526020017f785348333350000000000000000000000000000000000000000000000000000081525081600390805190602001906200012992919062000183565b5080600490805190602001906200014292919062000183565b5050508073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b815250505062000239565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620001bb576000855562000207565b82601f10620001d657805160ff191683800117855562000207565b8280016001018555821562000207579182015b8281111562000206578251825591602001919060010190620001e9565b5b5090506200021691906200021a565b5090565b5b80821115620002355760008160009055506001016200021b565b5090565b60805160601c612dc96200027a6000398061094a5280610d375280610e22528061124a528061150a528061170852806118ed5280611dde5250612dc96000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c806368a8847a116100de578063a457c2d711610097578063dd62ed3e11610071578063dd62ed3e14610736578063eaac6c13146107ae578063f2fde38b146107f0578063f630cfac1461083457610173565b8063a457c2d714610640578063a694fc3a146106a4578063a9059cbb146106d257610173565b806368a8847a146104b357806370a08231146104f5578063869890381461054d5780638da5cb5b1461056b57806395d89b411461059f5780639b42dfcb1461062257610173565b806323b872dd1161013057806323b872dd1461035457806324937781146103d85780632e17de78146103f6578063313ce5671461042457806339509351146104455780634e71e0c8146104a957610173565b806306fdde0314610178578063095ea7b3146101fb57806310120f5e1461025f57806315cfc4051461029357806316114acd146102f257806318160ddd14610336575b600080fd5b610180610893565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101c05780820151818401526020810190506101a5565b50505050905090810190601f1680156101ed5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102476004803603604081101561021157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610931565b60405180821515815260200191505060405180910390f35b610267610948565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102d5600480360360208110156102a957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061096c565b604051808381526020018281526020019250505060405180910390f35b6103346004803603602081101561030857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506109fe565b005b61033e610ba2565b6040518082815260200191505060405180910390f35b6103c06004803603606081101561036a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610ba8565b60405180821515815260200191505060405180910390f35b6103e0610ca1565b6040518082815260200191505060405180910390f35b6104226004803603602081101561040c57600080fd5b8101908080359060200190929190505050610ca7565b005b61042c610fa8565b604051808260ff16815260200191505060405180910390f35b6104916004803603604081101561045b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610fbb565b60405180821515815260200191505060405180910390f35b6104b1611060565b005b6104df600480360360208110156104c957600080fd5b81019080803590602001909291905050506111bb565b6040518082815260200191505060405180910390f35b6105376004803603602081101561050b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061132f565b6040518082815260200191505060405180910390f35b610555611377565b6040518082815260200191505060405180910390f35b61057361137d565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6105a76113a3565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156105e75780820151818401526020810190506105cc565b50505050905090810190601f1680156106145780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61062a611441565b6040518082815260200191505060405180910390f35b61068c6004803603604081101561065657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611447565b60405180821515815260200191505060405180910390f35b6106d0600480360360208110156106ba57600080fd5b8101908080359060200190929190505050611506565b005b61071e600480360360408110156106e857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506118ac565b60405180821515815260200191505060405180910390f35b6107986004803603604081101561074c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506118c3565b6040518082815260200191505060405180910390f35b6107da600480360360208110156107c457600080fd5b81019080803590602001909291905050506118e8565b6040518082815260200191505060405180910390f35b6108326004803603602081101561080657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611a81565b005b6108766004803603602081101561084a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611b88565b604051808381526020018281526020019250505060405180910390f35b60038054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156109295780601f106108fe57610100808354040283529160200191610929565b820191906000526020600020905b81548152906001019060200180831161090c57829003601f168201915b505050505081565b600061093e338484611bac565b6001905092915050565b7f000000000000000000000000000000000000000000000000000000000000000081565b600080600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000154600a60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001015491509150915091565b600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610ac1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f4f776e6572206f6e6c790000000000000000000000000000000000000000000081525060200191505060405180910390fd5b610aca81611da3565b610ad357600080fd5b610b9f338273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015610b3e57600080fd5b505afa158015610b52573d6000803e3d6000fd5b505050506040513d6020811015610b6857600080fd5b81019080805190602001909291905050508373ffffffffffffffffffffffffffffffffffffffff16611e349092919063ffffffff16565b50565b60025481565b6000610bb5848484611ed6565b6000600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610c9557610c948533610c8f86604051806060016040528060288152602001612cb360289139866121979092919063ffffffff16565b611bac565b5b60019150509392505050565b60095481565b60003073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610cef57600080fd5b505afa158015610d03573d6000803e3d6000fd5b505050506040513d6020811015610d1957600080fd5b810190808051906020019092919050505090506000610e1482610e067f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015610dbc57600080fd5b505afa158015610dd0573d6000803e3d6000fd5b505050506040513d6020811015610de657600080fd5b81019080805190602001909291905050508661225790919063ffffffff16565b6122dd90919063ffffffff16565b9050610e203384612327565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015610eb157600080fd5b505af1158015610ec5573d6000803e3d6000fd5b505050506040513d6020811015610edb57600080fd5b81019080805190602001909291905050505080600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160008282540192505081905550806009600082825401925050819055503373ffffffffffffffffffffffffffffffffffffffff167f1ad7634ff328dff8ac2b78189a71d0cac7225fe05e678451506a742e7fe4abee8442604051808381526020018281526020019250505060405180910390a2505050565b600560009054906101000a900460ff1681565b6000611056338461105185600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546124eb90919063ffffffff16565b611bac565b6001905092915050565b3373ffffffffffffffffffffffffffffffffffffffff16600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146110ba57600080fd5b6000600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055503373ffffffffffffffffffffffffffffffffffffffff16600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a333600560016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b6000803073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561120457600080fd5b505afa158015611218573d6000803e3d6000fd5b505050506040513d602081101561122e57600080fd5b81019080805190602001909291905050509050611327816113197f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156112cf57600080fd5b505afa1580156112e3573d6000803e3d6000fd5b505050506040513d60208110156112f957600080fd5b81019080805190602001909291905050508661225790919063ffffffff16565b6122dd90919063ffffffff16565b915050919050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60075481565b600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60048054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156114395780601f1061140e57610100808354040283529160200191611439565b820191906000526020600020905b81548152906001019060200180831161141c57829003601f168201915b505050505081565b60085481565b60006114fc33846114f785604051806060016040528060258152602001612d6f60259139600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546121979092919063ffffffff16565b611bac565b6001905092915050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561158f57600080fd5b505afa1580156115a3573d6000803e3d6000fd5b505050506040513d60208110156115b957600080fd5b8101908080519060200190929190505050905060003073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561161457600080fd5b505afa158015611628573d6000803e3d6000fd5b505050506040513d602081101561163e57600080fd5b810190808051906020019092919050505090506000600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015414156116ae5760016007600082825401925050819055505b60008114806116bd5750600082145b156116d1576116cc3384612573565b611706565b60006116f8836116ea848761225790919063ffffffff16565b6122dd90919063ffffffff16565b90506117043382612573565b505b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166323b872dd3330866040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b1580156117b557600080fd5b505af11580156117c9573d6000803e3d6000fd5b505050506040513d60208110156117df57600080fd5b81019080805190602001909291905050505082600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282540192505081905550826008600082825401925050819055503373ffffffffffffffffffffffffffffffffffffffff167f5e8d8c6de1918316cbb84e10a82139832a4eb6f3779be1fde50dbfe0a33c3fd48442604051808381526020018281526020019250505060405180910390a2505050565b60006118b9338484611ed6565b6001905092915050565b6001602052816000526040600020602052806000526040600020600091509150505481565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561197257600080fd5b505afa158015611986573d6000803e3d6000fd5b505050506040513d602081101561199c57600080fd5b8101908080519060200190929190505050905060003073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156119f757600080fd5b505afa158015611a0b573d6000803e3d6000fd5b505050506040513d6020811015611a2157600080fd5b810190808051906020019092919050505090506000811480611a435750600082145b15611a52578392505050611a7c565b611a7782611a69838761225790919063ffffffff16565b6122dd90919063ffffffff16565b925050505b919050565b600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611b44576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f4f776e6572206f6e6c790000000000000000000000000000000000000000000081525060200191505060405180910390fd5b80600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600a6020528060005260406000206000915090508060000154908060010154905082565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611c32576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526024815260200180612d216024913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611cb8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180612c246022913960400191505060405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040518082815260200191505060405180910390a3505050565b60003073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614158015611e2d57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b9050919050565b611ed18363a9059cbb60e01b8484604051602401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505061273a565b505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611f5c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180612cfc6025913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611fe2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180612bdf6023913960400191505060405180910390fd5b611fed838383612829565b61205881604051806060016040528060268152602001612c46602691396000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546121979092919063ffffffff16565b6000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506120eb816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546124eb90919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a3505050565b6000838311158290612244576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156122095780820151818401526020810190506121ee565b50505050905090810190601f1680156122365780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b60008083141561226a57600090506122d7565b600082840290508284828161227b57fe5b04146122d2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180612c926021913960400191505060405180910390fd5b809150505b92915050565b600061231f83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061282e565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156123ad576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180612cdb6021913960400191505060405180910390fd5b6123b982600083612829565b61242481604051806060016040528060228152602001612c02602291396000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546121979092919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061247b816002546128f490919063ffffffff16565b600281905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b600080828401905083811015612569576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612616576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f45524332303a206d696e7420746f20746865207a65726f20616464726573730081525060200191505060405180910390fd5b61262260008383612829565b612637816002546124eb90919063ffffffff16565b60028190555061268e816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546124eb90919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b606061279c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661293e9092919063ffffffff16565b9050600081511115612824578080602001905160208110156127bd57600080fd5b8101908080519060200190929190505050612823576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180612d45602a913960400191505060405180910390fd5b5b505050565b505050565b600080831182906128da576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561289f578082015181840152602081019050612884565b50505050905090810190601f1680156128cc5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385816128e657fe5b049050809150509392505050565b600061293683836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612197565b905092915050565b606061294d8484600085612956565b90509392505050565b6060824710156129b1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180612c6c6026913960400191505060405180910390fd5b6129ba85612aff565b612a2c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000081525060200191505060405180910390fd5b600060608673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b60208310612a7c5780518252602082019150602081019050602083039250612a59565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114612ade576040519150601f19603f3d011682016040523d82523d6000602084013e612ae3565b606091505b5091509150612af3828286612b12565b92505050949350505050565b600080823b905060008111915050919050565b60608315612b2257829050612bd7565b600083511115612b355782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612b9c578082015181840152602081019050612b81565b50505050905090810190601f168015612bc95780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b939250505056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e6365416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7745524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f20616464726573735361666545524332303a204552433230206f7065726174696f6e20646964206e6f74207375636365656445524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220ac6dea49f5935b8ab79c9faf3a85cfe8d0586d4ddbdc83d096e9db04d10ba3d764736f6c634300070400330000000000000000000000000694c9bf930b7456712cede98be770e110212b38
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101735760003560e01c806368a8847a116100de578063a457c2d711610097578063dd62ed3e11610071578063dd62ed3e14610736578063eaac6c13146107ae578063f2fde38b146107f0578063f630cfac1461083457610173565b8063a457c2d714610640578063a694fc3a146106a4578063a9059cbb146106d257610173565b806368a8847a146104b357806370a08231146104f5578063869890381461054d5780638da5cb5b1461056b57806395d89b411461059f5780639b42dfcb1461062257610173565b806323b872dd1161013057806323b872dd1461035457806324937781146103d85780632e17de78146103f6578063313ce5671461042457806339509351146104455780634e71e0c8146104a957610173565b806306fdde0314610178578063095ea7b3146101fb57806310120f5e1461025f57806315cfc4051461029357806316114acd146102f257806318160ddd14610336575b600080fd5b610180610893565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101c05780820151818401526020810190506101a5565b50505050905090810190601f1680156101ed5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102476004803603604081101561021157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610931565b60405180821515815260200191505060405180910390f35b610267610948565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102d5600480360360208110156102a957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061096c565b604051808381526020018281526020019250505060405180910390f35b6103346004803603602081101561030857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506109fe565b005b61033e610ba2565b6040518082815260200191505060405180910390f35b6103c06004803603606081101561036a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610ba8565b60405180821515815260200191505060405180910390f35b6103e0610ca1565b6040518082815260200191505060405180910390f35b6104226004803603602081101561040c57600080fd5b8101908080359060200190929190505050610ca7565b005b61042c610fa8565b604051808260ff16815260200191505060405180910390f35b6104916004803603604081101561045b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610fbb565b60405180821515815260200191505060405180910390f35b6104b1611060565b005b6104df600480360360208110156104c957600080fd5b81019080803590602001909291905050506111bb565b6040518082815260200191505060405180910390f35b6105376004803603602081101561050b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061132f565b6040518082815260200191505060405180910390f35b610555611377565b6040518082815260200191505060405180910390f35b61057361137d565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6105a76113a3565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156105e75780820151818401526020810190506105cc565b50505050905090810190601f1680156106145780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61062a611441565b6040518082815260200191505060405180910390f35b61068c6004803603604081101561065657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611447565b60405180821515815260200191505060405180910390f35b6106d0600480360360208110156106ba57600080fd5b8101908080359060200190929190505050611506565b005b61071e600480360360408110156106e857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506118ac565b60405180821515815260200191505060405180910390f35b6107986004803603604081101561074c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506118c3565b6040518082815260200191505060405180910390f35b6107da600480360360208110156107c457600080fd5b81019080803590602001909291905050506118e8565b6040518082815260200191505060405180910390f35b6108326004803603602081101561080657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611a81565b005b6108766004803603602081101561084a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611b88565b604051808381526020018281526020019250505060405180910390f35b60038054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156109295780601f106108fe57610100808354040283529160200191610929565b820191906000526020600020905b81548152906001019060200180831161090c57829003601f168201915b505050505081565b600061093e338484611bac565b6001905092915050565b7f0000000000000000000000000694c9bf930b7456712cede98be770e110212b3881565b600080600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000154600a60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001015491509150915091565b600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610ac1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f4f776e6572206f6e6c790000000000000000000000000000000000000000000081525060200191505060405180910390fd5b610aca81611da3565b610ad357600080fd5b610b9f338273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015610b3e57600080fd5b505afa158015610b52573d6000803e3d6000fd5b505050506040513d6020811015610b6857600080fd5b81019080805190602001909291905050508373ffffffffffffffffffffffffffffffffffffffff16611e349092919063ffffffff16565b50565b60025481565b6000610bb5848484611ed6565b6000600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610c9557610c948533610c8f86604051806060016040528060288152602001612cb360289139866121979092919063ffffffff16565b611bac565b5b60019150509392505050565b60095481565b60003073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610cef57600080fd5b505afa158015610d03573d6000803e3d6000fd5b505050506040513d6020811015610d1957600080fd5b810190808051906020019092919050505090506000610e1482610e067f0000000000000000000000000694c9bf930b7456712cede98be770e110212b3873ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015610dbc57600080fd5b505afa158015610dd0573d6000803e3d6000fd5b505050506040513d6020811015610de657600080fd5b81019080805190602001909291905050508661225790919063ffffffff16565b6122dd90919063ffffffff16565b9050610e203384612327565b7f0000000000000000000000000694c9bf930b7456712cede98be770e110212b3873ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015610eb157600080fd5b505af1158015610ec5573d6000803e3d6000fd5b505050506040513d6020811015610edb57600080fd5b81019080805190602001909291905050505080600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160008282540192505081905550806009600082825401925050819055503373ffffffffffffffffffffffffffffffffffffffff167f1ad7634ff328dff8ac2b78189a71d0cac7225fe05e678451506a742e7fe4abee8442604051808381526020018281526020019250505060405180910390a2505050565b600560009054906101000a900460ff1681565b6000611056338461105185600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546124eb90919063ffffffff16565b611bac565b6001905092915050565b3373ffffffffffffffffffffffffffffffffffffffff16600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146110ba57600080fd5b6000600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055503373ffffffffffffffffffffffffffffffffffffffff16600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a333600560016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b6000803073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561120457600080fd5b505afa158015611218573d6000803e3d6000fd5b505050506040513d602081101561122e57600080fd5b81019080805190602001909291905050509050611327816113197f0000000000000000000000000694c9bf930b7456712cede98be770e110212b3873ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156112cf57600080fd5b505afa1580156112e3573d6000803e3d6000fd5b505050506040513d60208110156112f957600080fd5b81019080805190602001909291905050508661225790919063ffffffff16565b6122dd90919063ffffffff16565b915050919050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60075481565b600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60048054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156114395780601f1061140e57610100808354040283529160200191611439565b820191906000526020600020905b81548152906001019060200180831161141c57829003601f168201915b505050505081565b60085481565b60006114fc33846114f785604051806060016040528060258152602001612d6f60259139600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546121979092919063ffffffff16565b611bac565b6001905092915050565b60007f0000000000000000000000000694c9bf930b7456712cede98be770e110212b3873ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561158f57600080fd5b505afa1580156115a3573d6000803e3d6000fd5b505050506040513d60208110156115b957600080fd5b8101908080519060200190929190505050905060003073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561161457600080fd5b505afa158015611628573d6000803e3d6000fd5b505050506040513d602081101561163e57600080fd5b810190808051906020019092919050505090506000600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015414156116ae5760016007600082825401925050819055505b60008114806116bd5750600082145b156116d1576116cc3384612573565b611706565b60006116f8836116ea848761225790919063ffffffff16565b6122dd90919063ffffffff16565b90506117043382612573565b505b7f0000000000000000000000000694c9bf930b7456712cede98be770e110212b3873ffffffffffffffffffffffffffffffffffffffff166323b872dd3330866040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b1580156117b557600080fd5b505af11580156117c9573d6000803e3d6000fd5b505050506040513d60208110156117df57600080fd5b81019080805190602001909291905050505082600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282540192505081905550826008600082825401925050819055503373ffffffffffffffffffffffffffffffffffffffff167f5e8d8c6de1918316cbb84e10a82139832a4eb6f3779be1fde50dbfe0a33c3fd48442604051808381526020018281526020019250505060405180910390a2505050565b60006118b9338484611ed6565b6001905092915050565b6001602052816000526040600020602052806000526040600020600091509150505481565b6000807f0000000000000000000000000694c9bf930b7456712cede98be770e110212b3873ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561197257600080fd5b505afa158015611986573d6000803e3d6000fd5b505050506040513d602081101561199c57600080fd5b8101908080519060200190929190505050905060003073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156119f757600080fd5b505afa158015611a0b573d6000803e3d6000fd5b505050506040513d6020811015611a2157600080fd5b810190808051906020019092919050505090506000811480611a435750600082145b15611a52578392505050611a7c565b611a7782611a69838761225790919063ffffffff16565b6122dd90919063ffffffff16565b925050505b919050565b600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611b44576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f4f776e6572206f6e6c790000000000000000000000000000000000000000000081525060200191505060405180910390fd5b80600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600a6020528060005260406000206000915090508060000154908060010154905082565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611c32576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526024815260200180612d216024913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611cb8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180612c246022913960400191505060405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040518082815260200191505060405180910390a3505050565b60003073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614158015611e2d57507f0000000000000000000000000694c9bf930b7456712cede98be770e110212b3873ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b9050919050565b611ed18363a9059cbb60e01b8484604051602401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505061273a565b505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611f5c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180612cfc6025913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611fe2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180612bdf6023913960400191505060405180910390fd5b611fed838383612829565b61205881604051806060016040528060268152602001612c46602691396000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546121979092919063ffffffff16565b6000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506120eb816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546124eb90919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a3505050565b6000838311158290612244576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156122095780820151818401526020810190506121ee565b50505050905090810190601f1680156122365780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b60008083141561226a57600090506122d7565b600082840290508284828161227b57fe5b04146122d2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180612c926021913960400191505060405180910390fd5b809150505b92915050565b600061231f83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061282e565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156123ad576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180612cdb6021913960400191505060405180910390fd5b6123b982600083612829565b61242481604051806060016040528060228152602001612c02602291396000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546121979092919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061247b816002546128f490919063ffffffff16565b600281905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b600080828401905083811015612569576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612616576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f45524332303a206d696e7420746f20746865207a65726f20616464726573730081525060200191505060405180910390fd5b61262260008383612829565b612637816002546124eb90919063ffffffff16565b60028190555061268e816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546124eb90919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b606061279c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661293e9092919063ffffffff16565b9050600081511115612824578080602001905160208110156127bd57600080fd5b8101908080519060200190929190505050612823576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180612d45602a913960400191505060405180910390fd5b5b505050565b505050565b600080831182906128da576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561289f578082015181840152602081019050612884565b50505050905090810190601f1680156128cc5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385816128e657fe5b049050809150509392505050565b600061293683836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612197565b905092915050565b606061294d8484600085612956565b90509392505050565b6060824710156129b1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180612c6c6026913960400191505060405180910390fd5b6129ba85612aff565b612a2c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000081525060200191505060405180910390fd5b600060608673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b60208310612a7c5780518252602082019150602081019050602083039250612a59565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114612ade576040519150601f19603f3d011682016040523d82523d6000602084013e612ae3565b606091505b5091509150612af3828286612b12565b92505050949350505050565b600080823b905060008111915050919050565b60608315612b2257829050612bd7565b600083511115612b355782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612b9c578082015181840152602081019050612b81565b50505050905090810190601f168015612bc95780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b939250505056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e6365416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7745524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f20616464726573735361666545524332303a204552433230206f7065726174696f6e20646964206e6f74207375636365656445524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220ac6dea49f5935b8ab79c9faf3a85cfe8d0586d4ddbdc83d096e9db04d10ba3d764736f6c63430007040033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000000694c9bf930b7456712cede98be770e110212b38
-----Decoded View---------------
Arg [0] : _rooted (address): 0x0694c9bf930b7456712cede98be770e110212b38
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000000694c9bf930b7456712cede98be770e110212b38
Deployed ByteCode Sourcemap
182:3015:53:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;385:27:4;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;919:167;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;301:30:53;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;863:233;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;427:196:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;341:35:4;;;:::i;:::-;;;;;;;;;;;;;;;;;;;1094:420;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;409:30:53;;;:::i;:::-;;;;;;;;;;;;;;;;;;;2550:463;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;455:35:4;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;1522:212;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;653:222:44;;;:::i;:::-;;1494:219:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;628:102:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;340:27:53;;;:::i;:::-;;;;;;;;;;;;;;;;;;;330:42:44;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;419:29:4;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;374:28:53;;;:::i;:::-;;;;;;;;;;;;;;;;;;;1742:263:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;1762:738:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;738:173:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;257:75;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;1104:382:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;525:120:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;548:55:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;385:27:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;919:167::-;1002:4;1019:37;1028:10;1040:7;1049:6;1019:8;:37::i;:::-;1074:4;1067:11;;919:167;;;;:::o;301:30:53:-;;;:::o;863:233::-;916:20;938:22;995:13;:20;1009:5;995:20;;;;;;;;;;;;;;;:32;;;1043:13;:20;1057:5;1043:20;;;;;;;;;;;;;;;:34;;;973:115;;;;863:233;;;:::o;427:196:56:-;477:5:44;;;;;;;;;;;463:19;;:10;:19;;;454:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;518:23:56::1;535:5;518:16;:23::i;:::-;509:33;;;::::0;::::1;;553:62;572:10;584:5;:15;;;608:4;584:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;553:5;:18;;;;:62;;;;;:::i;:::-;427:196:::0;:::o;341:35:4:-;;;;:::o;1094:420::-;1200:4;1217:36;1227:6;1235:9;1246:6;1217:9;:36::i;:::-;1264:20;1287:9;:17;1297:6;1287:17;;;;;;;;;;;;;;;:29;1305:10;1287:29;;;;;;;;;;;;;;;;1264:52;;1355:2;1331:12;:27;1327:158;;1375:98;1384:6;1392:10;1404:68;1421:6;1404:68;;;;;;;;;;;;;;;;;:12;:16;;:68;;;;;:::i;:::-;1375:8;:98::i;:::-;1327:158;1502:4;1495:11;;;1094:420;;;;;:::o;409:30:53:-;;;;:::o;2550:463::-;2600:19;2622:4;:16;;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2600:40;;2651:21;2675:59;2722:11;2675:42;2685:6;:16;;;2710:4;2685:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2675:5;:9;;:42;;;;:::i;:::-;:46;;:59;;;;:::i;:::-;2651:83;;2747:24;2753:10;2765:5;2747;:24::i;:::-;2782:6;:15;;;2798:10;2810:13;2782:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2880:13;2837;:25;2851:10;2837:25;;;;;;;;;;;;;;;:39;;;:56;;;;;;;;;;;2923:13;2904:15;;:32;;;;;;;;;;;2970:10;2954:51;;;2982:5;2989:15;2954:51;;;;;;;;;;;;;;;;;;;;;;;;2550:463;;;:::o;455:35:4:-;;;;;;;;;;;;;:::o;1522:212::-;1610:4;1627:77;1636:10;1648:7;1657:46;1692:10;1657:9;:21;1667:10;1657:21;;;;;;;;;;;;;;;:30;1679:7;1657:30;;;;;;;;;;;;;;;;:34;;:46;;;;:::i;:::-;1627:8;:77::i;:::-;1722:4;1715:11;;1522:212;;;;:::o;653:222:44:-;736:10;720:26;;:12;;;;;;;;;;;:26;;;711:36;;;;;;781:1;758:12;;:25;;;;;;;;;;;;;;;;;;827:10;799:39;;820:5;;;;;;;;;;;799:39;;;;;;;;;;;;857:10;849:5;;:18;;;;;;;;;;;;;;;;;;653:222::o;1494:219:53:-;1554:19;1586;1608:4;:16;;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1586:40;;1644:61;1693:11;1644:44;1656:6;:16;;;1681:4;1656:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1644:7;:11;;:44;;;;:::i;:::-;:48;;:61;;;;:::i;:::-;1637:68;;;1494:219;;;:::o;628:102:4:-;696:7;714:10;:13;725:1;714:13;;;;;;;;;;;;;;;;707:20;;628:102;;;:::o;340:27:53:-;;;;:::o;330:42:44:-;;;;;;;;;;;;;:::o;419:29:4:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;374:28:53:-;;;;:::o;1742:263:4:-;1835:4;1852:123;1861:10;1873:7;1882:92;1917:15;1882:92;;;;;;;;;;;;;;;;;:9;:21;1892:10;1882:21;;;;;;;;;;;;;;;:30;1904:7;1882:30;;;;;;;;;;;;;;;;:34;;:92;;;;;:::i;:::-;1852:8;:123::i;:::-;1993:4;1986:11;;1742:263;;;;:::o;1762:738:53:-;1811:19;1833:6;:16;;;1858:4;1833:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1811:53;;1875:19;1897:4;:16;;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1875:40;;1973:1;1932:13;:25;1946:10;1932:25;;;;;;;;;;;;;;;:37;;;:42;1928:92;;;2007:1;1991:12;;:17;;;;;;;;;;;1928:92;2051:1;2036:11;:16;:36;;;;2071:1;2056:11;:16;2036:36;2032:232;;;2089:25;2095:10;2107:6;2089:5;:25::i;:::-;2032:232;;;2147:18;2168:40;2196:11;2168:23;2179:11;2168:6;:10;;:23;;;;:::i;:::-;:27;;:40;;;;:::i;:::-;2147:61;;2223:29;2229:10;2241;2223:5;:29::i;:::-;2032:232;;2276:6;:19;;;2296:10;2316:4;2323:6;2276:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2384:6;2343:13;:25;2357:10;2343:25;;;;;;;;;;;;;;;:37;;;:47;;;;;;;;;;;2418:6;2401:13;;:23;;;;;;;;;;;2456:10;2442:50;;;2468:6;2476:15;2442:50;;;;;;;;;;;;;;;;;;;;;;;;1762:738;;;:::o;738:173:4:-;824:4;841:40;851:10;863:9;874:6;841:9;:40::i;:::-;899:4;892:11;;738:173;;;;:::o;257:75::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;1104:382:53:-;1164:21;1198:19;1220:6;:16;;;1245:4;1220:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1198:53;;1262:19;1284:4;:16;;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1262:40;;1334:1;1319:11;:16;:36;;;;1354:1;1339:11;:16;1319:36;1315:164;;;1379:7;1372:14;;;;;;1315:164;1426:41;1455:11;1426:24;1438:11;1426:7;:11;;:24;;;;:::i;:::-;:28;;:41;;;;:::i;:::-;1419:48;;;;1104:382;;;;:::o;525:120:44:-;477:5;;;;;;;;;;;463:19;;:10;:19;;;454:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;629:8:::1;614:12;;:23;;;;;;;;;;;;;;;;;;525:120:::0;:::o;548:55:53:-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;3376:344:4:-;3495:1;3478:19;;:5;:19;;;;3470:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3576:1;3557:21;;:7;:21;;;;3549:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3658:6;3630:9;:16;3640:5;3630:16;;;;;;;;;;;;;;;:25;3647:7;3630:25;;;;;;;;;;;;;;;:34;;;;3696:7;3680:32;;3689:5;3680:32;;;3705:6;3680:32;;;;;;;;;;;;;;;;;;3376:344;;;:::o;3021:173:53:-;3093:4;3143;3117:31;;3125:5;3117:31;;;;:68;;;;;3178:6;3152:33;;3160:5;3152:33;;;;3117:68;3110:75;;3021:173;;;:::o;829:177:51:-;912:86;932:5;962:23;;;987:2;991:5;939:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;912:19;:86::i;:::-;829:177;;;:::o;2013:543:4:-;2137:1;2119:20;;:6;:20;;;;2111:70;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2221:1;2200:23;;:9;:23;;;;2192:71;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2276:47;2297:6;2305:9;2316:6;2276:20;:47::i;:::-;2357:72;2380:6;2357:72;;;;;;;;;;;;;;;;;:10;:18;2368:6;2357:18;;;;;;;;;;;;;;;;:22;;:72;;;;;:::i;:::-;2336:10;:18;2347:6;2336:18;;;;;;;;;;;;;;;:93;;;;2464:33;2490:6;2464:10;:21;2475:9;2464:21;;;;;;;;;;;;;;;;:25;;:33;;;;:::i;:::-;2440:10;:21;2451:9;2440:21;;;;;;;;;;;;;;;:57;;;;2530:9;2513:35;;2522:6;2513:35;;;2541:6;2513:35;;;;;;;;;;;;;;;;;;2013:543;;;:::o;441:196:52:-;527:7;566:1;561;:6;;569:12;553:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;593:9;609:1;605;:5;593:17;;628:1;621:8;;;441:196;;;;;:::o;645:485::-;703:7;959:1;954;:6;950:57;;;994:1;987:8;;;;950:57;1019:9;1035:1;1031;:5;1019:17;;1064:1;1059;1055;:5;;;;;;:10;1047:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1121:1;1114:8;;;645:485;;;;;:::o;1142:138::-;1200:7;1233:39;1237:1;1240;1233:39;;;;;;;;;;;;;;;;;:3;:39::i;:::-;1226:46;;1142:138;;;;:::o;2950:418:4:-;3053:1;3034:21;;:7;:21;;;;3026:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3106:49;3127:7;3144:1;3148:6;3106:20;:49::i;:::-;3190:69;3214:6;3190:69;;;;;;;;;;;;;;;;;:10;:19;3201:7;3190:19;;;;;;;;;;;;;;;;:23;;:69;;;;;:::i;:::-;3168:10;:19;3179:7;3168:19;;;;;;;;;;;;;;;:91;;;;3284:23;3300:6;3284:11;;:15;;:23;;;;:::i;:::-;3270:11;:37;;;;3349:1;3323:37;;3332:7;3323:37;;;3353:6;3323:37;;;;;;;;;;;;;;;;;;2950:418;;:::o;98:185:52:-;156:7;182:9;198:1;194;:5;182:17;;223:1;218;:6;;210:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;274:1;267:8;;;98:185;;;;:::o;2564:378:4:-;2667:1;2648:21;;:7;:21;;;;2640:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2718:49;2747:1;2751:7;2760:6;2718:20;:49::i;:::-;2794:23;2810:6;2794:11;;:15;;:23;;;;:::i;:::-;2780:11;:37;;;;2850:31;2874:6;2850:10;:19;2861:7;2850:19;;;;;;;;;;;;;;;;:23;;:31;;;;:::i;:::-;2828:10;:19;2839:7;2828:19;;;;;;;;;;;;;;;:53;;;;2918:7;2897:37;;2914:1;2897:37;;;2927:6;2897:37;;;;;;;;;;;;;;;;;;2564:378;;:::o;2072:761:51:-;2496:23;2522:69;2550:4;2522:69;;;;;;;;;;;;;;;;;2530:5;2522:27;;;;:69;;;;;:::i;:::-;2496:95;;2626:1;2606:10;:17;:21;2602:224;;;2748:10;2737:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2729:85;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2602:224;2072:761;;;:::o;3825:92:4:-;;;;:::o;1288:195:52:-;1374:7;1412:1;1408;:5;1415:12;1400:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1439:9;1455:1;1451;:5;;;;;;1439:17;;1474:1;1467:8;;;1288:195;;;;;:::o;291:142::-;349:7;382:43;386:1;389;382:43;;;;;;;;;;;;;;;;;:3;:43::i;:::-;375:50;;291:142;;;;:::o;783:195:0:-;886:12;918:52;940:6;948:4;954:1;957:12;918:21;:52::i;:::-;911:59;;783:195;;;;;:::o;1220:470::-;1347:12;1405:5;1380:21;:30;;1372:81;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1472:18;1483:6;1472:10;:18::i;:::-;1464:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1538:12;1552:23;1579:6;:11;;1599:5;1607:4;1579:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1537:75;;;;1630:52;1648:7;1657:10;1669:12;1630:17;:52::i;:::-;1623:59;;;;1220:470;;;;;;:::o;95:174::-;155:4;172:12;226:7;214:20;206:28;;260:1;253:4;:8;246:15;;;95:174;;;:::o;2852:515::-;2967:12;2996:7;2992:368;;;3027:10;3020:17;;;;2992:368;3094:1;3074:10;:17;:21;3070:279;;;3177:10;3171:17;3238:15;3225:10;3221:2;3217:19;3210:44;3125:148;3320:12;3313:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2852:515;;;;;;:::o
Swarm Source
ipfs://ac6dea49f5935b8ab79c9faf3a85cfe8d0586d4ddbdc83d096e9db04d10ba3d7