Description:
Smart contract deployed on Ethereum.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
/**
*Submitted for verification at testnet.bscscan.com on 2025-09-08
*/
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() {
_transferOwnership(_msgSender());
}
modifier onlyOwner() {
_checkOwner();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
library TransferHelper {
function safeTransfer(address token, address to, uint value) internal {
// bytes4(keccak256(bytes('transfer(address,uint256)')));
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value));
require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FAILED');
}
function safeTransferFrom(address token, address from, address to, uint value) internal {
// bytes4(keccak256(bytes('transferFrom(address,address,uint256)')));
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value));
require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FROM_FAILED');
}
}
interface IERC20 {
function balanceOf(address account) external view returns (uint256);
}
abstract contract ReentrancyGuard {
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
modifier nonReentrant() {
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
_status = _ENTERED;
_;
_status = _NOT_ENTERED;
}
}
contract BMBTokenStake is Ownable, ReentrancyGuard {
address public addressBMB = 0x9447dd95f576fdF6ED8219ffF45BD1362430B787;
address public addressBMC = 0x0cA7244F798765De51A2b911f16EbCb7367362d1;
uint256 public stakeMinBMB = 100000;
uint256 public stakeMinBMC = 100000;
uint256 public unStakeTimeBMB = 4000000000; // ʼʱ
uint256 public unStakeTimeBMC = 4000000000; // ʼʱ
uint256 public releaseDaysBMB = 180;
uint256 public releaseDaysBMC = 180;
uint256 constant public secondsPerDay = 86400; // ʱ 100 ʾ100 һ 죬 86400
struct StakeInfo {
uint256 id;
address user; // Ѻ û
address token; // Ѻ Ĵ
uint256 time; // Ѻʱ
uint256 stakeAmt; // Ѻ
}
StakeInfo[] public stakeInfos; // Ѻ Ϣ-ÿ Ѻ
mapping (address => mapping (address => uint256)) public userTokenStakeAmt; // û Ѻij ҵ û => =>
mapping (address => mapping (address => uint256)) public userTokenUnStakeAmt; // û ij ҵ û => =>
constructor() {
stakeInfos.push(StakeInfo({id:1,user:address(0),token:address(0),time:0,stakeAmt:0}));
}
// Ѻ token Լ ַ stakeAmt_ û 100000 Ȩ Լ
function stakeToken(address token_, uint256 stakeAmt_) external nonReentrant {
require(_msgSender() == tx.origin, "Can not from contract.");
require(addressBMB == token_ || addressBMC == token_, "Token Not Support.");
if (addressBMB == token_) {
require(block.timestamp < unStakeTimeBMB, "Stake Stopped.");
require(stakeAmt_ >= stakeMinBMB, "Below the minimum investment amount.");
if (unStakeTimeBMB == 4000000000) {
unStakeTimeBMB = block.timestamp + releaseDaysBMB * secondsPerDay;
}
} else if (addressBMC == token_) {
require(block.timestamp < unStakeTimeBMC, "Stake Stopped.");
require(stakeAmt_ >= stakeMinBMC, "Below the minimum investment amount.");
if (unStakeTimeBMC == 4000000000) {
unStakeTimeBMC = block.timestamp + releaseDaysBMC * secondsPerDay;
}
}
require(IERC20(token_).balanceOf(_msgSender()) >= stakeAmt_, "Balance Not Enough.");
TransferHelper.safeTransferFrom(token_, _msgSender(), address(this), stakeAmt_);
StakeInfo memory di = StakeInfo({
id: stakeInfos.length + 1,
user: _msgSender(),
token: token_,
time: block.timestamp,
stakeAmt: stakeAmt_
});
stakeInfos.push(di);
userTokenStakeAmt[_msgSender()][token_] += stakeAmt_;
}
function redemption(address token_) external nonReentrant {
require(addressBMB == token_ || addressBMC == token_, "Token Not Support.");
if (addressBMB == token_) {
require(block.timestamp >= unStakeTimeBMB, "UnStake Not Start.");
} else if (addressBMC == token_) {
require(block.timestamp >= unStakeTimeBMC, "UnStake Not Start.");
}
uint256 _returnAmt = userTokenStakeAmt[_msgSender()][token_] - userTokenUnStakeAmt[_msgSender()][token_];
require(_returnAmt > 0, "No Token To Claim.");
userTokenUnStakeAmt[_msgSender()][token_] += _returnAmt;
TransferHelper.safeTransfer(token_, _msgSender(), _returnAmt);
}
// ȡ û Ѻ Ϣ _user 뵱ǰ û ĵ ַ,token_ Һ Լ
// أ
// _minAmt ǰ ҵ С Ѻ
// _stakeAmt ǰ û ǰ ܹ Ѻ صģ
// _unStakeAmt ǰ û ǰ ܹ ص
// _canUnStakeAmt ǰ û ǰ ҿ ص
// ذ ť _canUnStakeAmt > 0ʱ Ե ʱ redemption
function getStakeInfos(address _user, address token_) public view returns(
uint256 _minAmt, uint256 _stakeAmt, uint256 _unStakeAmt, uint256 _canUnStakeAmt) {
if (addressBMB == token_) {
_minAmt = stakeMinBMB;
if (block.timestamp >= unStakeTimeBMB) {
_canUnStakeAmt = userTokenStakeAmt[_user][token_] - userTokenUnStakeAmt[_user][token_];
} else {
_canUnStakeAmt = 0;
}
} else if (addressBMC == token_) {
_minAmt = stakeMinBMC;
if (block.timestamp >= unStakeTimeBMC) {
_canUnStakeAmt = userTokenStakeAmt[_user][token_] - userTokenUnStakeAmt[_user][token_];
} else {
_canUnStakeAmt = 0;
}
}
return (_minAmt, userTokenStakeAmt[_user][token_], userTokenUnStakeAmt[_user][token_], _canUnStakeAmt);
}
function rescueToken(address tokenAddr_, uint256 amt_) external onlyOwner {
TransferHelper.safeTransfer(tokenAddr_, owner(), amt_);
}
function rescueETH() external onlyOwner {
uint256 balance = address(this).balance;
payable(owner()).transfer(balance);
}
}
Submitted on: 2025-09-22 12:42:50
Comments
Log in to comment.
No comments yet.