Overview
ETH Balance
0 ETH
ETH Value
$0.00
Cross-Chain Transactions
Loading...
Loading
Minimal Proxy Contract for 0x7e28a1d82c5b7cee795affd555a398be18301f71
Contract Name:
GameLockStaking
Compiler Version
v0.8.20+commit.a1b79de6
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;
import "./Ownable.sol";
import {IBlast, IBlastPoints} from "./interfaces/IBlast.sol";
import {IGameLockStakingFactory} from "./interfaces/IGameLockStakingFactory.sol";
contract GameLockStaking is Ownable {
bool private initialized = false;
uint256 public constant MIN_LOCK_DURATION = 15 days;
uint256 public constant MAX_LOCK_DURATION = 180 days;
IBlast public constant BLAST =
IBlast(0x4300000000000000000000000000000000000002);
IGameLockStakingFactory public factory;
event Staked(address indexed user, uint256 amount, uint256 duration);
event Unstaked(address indexed user, uint256 amount);
event GasClaimed(address indexed user, uint256 amount);
event YieldClaimed(address indexed user, uint256 amount);
event WithdrawnAll(address indexed recipient, uint256 amount);
uint256 public dueTime;
uint256 public stakeChangesAt;
uint256 public totalStaked;
uint256 public totalYield;
uint256 public totalGas;
uint256 public lockedValue;
constructor() {}
function initialize(
address _initialOwner,
address _blastPointsAddress,
address _pointsOperator,
address _factory
) public {
require(!initialized, "GameLockStaking: Initialized before");
initialized = true;
_owner = _initialOwner;
factory = IGameLockStakingFactory(_factory);
BLAST.configureClaimableGas();
IBlastPoints(_blastPointsAddress).configurePointsOperator(
_pointsOperator
);
BLAST.configureClaimableYield();
}
function claimAllGas() external {
uint256 gasReceived = BLAST.claimMaxGas(address(this), owner());
require(gasReceived > 0, "GameLockStaking: No gas");
totalGas += gasReceived;
emit GasClaimed(owner(), gasReceived);
}
function claimAllYield() external {
uint256 yieldReceived = BLAST.claimAllYield(
address(this),
address(this)
);
require(yieldReceived > 0, "GameLockStaking: No yield");
totalYield += yieldReceived;
emit YieldClaimed(owner(), yieldReceived);
payable(owner()).transfer(yieldReceived);
}
function stake(uint256 _duration) external payable onlyOwner {
require(msg.value > 0, "GameLockStaking: Zero amount");
require(_duration > 0, "GameLockStaking: Invalid duration");
require(
_duration % MIN_LOCK_DURATION == 0,
"GameLockStaking: Invalid duration - must be multiple of 15 days"
);
require(
_duration <= MAX_LOCK_DURATION,
"GameLockStaking: Max lock - 180 days"
);
require(
_duration >= dueTime - stakeChangesAt,
"GameLockStaking: Less than last duration"
);
uint256 decreaseAmount = 0;
if (dueTime > block.timestamp) {
decreaseAmount = totalStaked * (dueTime - block.timestamp);
}
totalStaked += msg.value;
dueTime = block.timestamp + _duration;
lockedValue += (totalStaked * _duration) - decreaseAmount;
stakeChangesAt = block.timestamp;
emit Staked(owner(), msg.value, _duration);
}
function unstake(uint256 _amount) external onlyOwner {
require(totalStaked > 0, "GameLockStaking: Not staked");
require(
_amount > 0 && _amount <= totalStaked,
"GameLockStaking: Invalid amount"
);
require(block.timestamp >= dueTime, "GameLockStaking: Not due yet");
totalStaked -= _amount;
emit Unstaked(owner(), _amount);
payable(owner()).transfer(_amount);
}
function withdrawAll() external onlyOwner {
uint256 balance = address(this).balance;
require(balance > 0, "GameLockStaking: Empty balance");
require(block.timestamp >= dueTime, "GameLockStaking: Not due yet");
totalStaked = 0;
emit WithdrawnAll(owner(), balance);
payable(owner()).transfer(balance);
}
function transferOwnership(address _newOwner) public override onlyOwner {
require(_newOwner != address(0), "Ownable: Zero Address");
address _currentOwner = _owner;
_owner = _newOwner;
emit OwnershipTransferred(_currentOwner, _newOwner);
factory.setCloneNewOwner(_newOwner, _currentOwner);
}
function readClaimableYield() external view returns (uint256) {
return BLAST.readClaimableYield(address(this));
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;
contract Ownable {
address public _owner;
event OwnershipTransferred(
address indexed previousOwner,
address indexed newOwner
);
constructor() {}
modifier onlyOwner() {
require(isOwner(), "Ownable: Not owner");
_;
}
function owner() public view returns (address) {
return _owner;
}
function isOwner() public view returns (bool) {
return msg.sender == _owner;
}
function renounceOwnership() public virtual onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(
newOwner != address(0),
"Ownable: Zero Address"
);
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
enum YieldMode {
AUTOMATIC,
VOID,
CLAIMABLE
}
enum GasMode {
VOID,
CLAIMABLE
}
interface IBlast {
// configure
function configureContract(
address contractAddress,
YieldMode _yield,
GasMode gasMode,
address governor
) external;
function configure(
YieldMode _yield,
GasMode gasMode,
address governor
) external;
// base configuration options
function configureClaimableYield() external;
function configureClaimableYieldOnBehalf(address contractAddress) external;
function configureAutomaticYield() external;
function configureAutomaticYieldOnBehalf(address contractAddress) external;
function configureVoidYield() external;
function configureVoidYieldOnBehalf(address contractAddress) external;
function configureClaimableGas() external;
function configureClaimableGasOnBehalf(address contractAddress) external;
function configureVoidGas() external;
function configureVoidGasOnBehalf(address contractAddress) external;
function configureGovernor(address _governor) external;
function configureGovernorOnBehalf(
address _newGovernor,
address contractAddress
) external;
// claim yield
function claimYield(
address contractAddress,
address recipientOfYield,
uint256 amount
) external returns (uint256);
function claimAllYield(
address contractAddress,
address recipientOfYield
) external returns (uint256);
// claim gas
function claimAllGas(
address contractAddress,
address recipientOfGas
) external returns (uint256);
function claimGasAtMinClaimRate(
address contractAddress,
address recipientOfGas,
uint256 minClaimRateBips
) external returns (uint256);
function claimMaxGas(
address contractAddress,
address recipientOfGas
) external returns (uint256);
function claimGas(
address contractAddress,
address recipientOfGas,
uint256 gasToClaim,
uint256 gasSecondsToConsume
) external returns (uint256);
// read functions
function readClaimableYield(
address contractAddress
) external view returns (uint256);
function readYieldConfiguration(
address contractAddress
) external view returns (uint8);
function readGasParams(
address contractAddress
)
external
view
returns (
uint256 etherSeconds,
uint256 etherBalance,
uint256 lastUpdated,
GasMode
);
}
interface IERC20Rebasing is IERC20 {
// changes the yield mode of the caller and update the balance
// to reflect the configuration
function configure(YieldMode) external returns (uint256);
// "claimable" yield mode accounts can call this this claim their yield
// to another address
function claim(
address recipient,
uint256 amount
) external returns (uint256);
// read the claimable amount for an account
function getClaimableAmount(
address account
) external view returns (uint256);
}
interface IBlastPoints {
function configurePointsOperator(address operator) external;
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;
interface IGameLockStakingFactory {
function createGameLockStakingClone() external returns (address);
function setGameLockStakingImplementation(
address _gameLockStakingImplementation
) external;
function setPointsOperator(address _pointsOperator) external;
function setCloneNewOwner(
address _newOwner,
address _currentOwner
) external;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC-20 standard as defined in the ERC.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 value) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 value) external returns (bool);
}{
"remappings": [
"@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
"@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
"@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
"@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
"ds-test/=lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/src/",
"erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
"forge-std/=lib/forge-std/src/",
"openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
"openzeppelin-contracts/=lib/openzeppelin-contracts/"
],
"optimizer": {
"enabled": true,
"runs": 200
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "paris",
"viaIR": false,
"libraries": {}
}Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"GasClaimed","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":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"duration","type":"uint256"}],"name":"Staked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Unstaked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WithdrawnAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"YieldClaimed","type":"event"},{"inputs":[],"name":"BLAST","outputs":[{"internalType":"contract IBlast","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_LOCK_DURATION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_LOCK_DURATION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimAllGas","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimAllYield","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"dueTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"contract IGameLockStakingFactory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_initialOwner","type":"address"},{"internalType":"address","name":"_blastPointsAddress","type":"address"},{"internalType":"address","name":"_pointsOperator","type":"address"},{"internalType":"address","name":"_factory","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockedValue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"readClaimableYield","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_duration","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"stakeChangesAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalGas","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalYield","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"unstake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawAll","outputs":[],"stateMutability":"nonpayable","type":"function"}]Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.