Feature Tip: Add private address tag to any address under My Name Tag !
Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
AMBXStaking
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 "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import "@openzeppelin/contracts/utils/Pausable.sol";
/**
* @title AMBX Staking Contract
* @notice Stake AMBX tokens to earn rewards with tiered APY based on lock period
* @dev Part of the AMBX ecosystem - Patent US 63/741,861
*
* Staking Tiers:
* - 30 days: 5% APY (1.0x multiplier)
* - 90 days: 8% APY (1.6x multiplier)
* - 180 days: 12% APY (2.4x multiplier)
* - 365 days: 15% APY (3.0x multiplier)
*/
contract AMBXStaking is AccessControl, ReentrancyGuard, Pausable {
using SafeERC20 for IERC20;
// ============ Structures ============
struct Stake {
uint256 amount; // Amount of AMBX staked
uint256 startTime; // When stake was created
uint256 lockPeriod; // Lock duration in seconds
uint256 apr; // APR in basis points (500 = 5%)
uint256 rewardsClaimed; // Total rewards claimed
bool active; // Whether stake is active
}
struct StakingTier {
uint256 lockPeriod; // Lock period in seconds
uint256 apr; // APR in basis points (500 = 5%)
uint256 multiplier; // Reward multiplier (100 = 1.0x)
bool active; // Whether tier is active
}
// ============ Constants ============
bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE");
bytes32 public constant OPERATOR_ROLE = keccak256("OPERATOR_ROLE");
uint256 public constant BASIS_POINTS = 10000; // 100%
uint256 public constant SECONDS_PER_YEAR = 365 days;
// ============ State Variables ============
IERC20 public immutable ambxToken;
/// @notice User stakes mapping
mapping(address => Stake[]) public userStakes;
/// @notice Staking tiers (lock period => tier details)
mapping(uint256 => StakingTier) public stakingTiers;
/// @notice Total staked across all users
uint256 public totalStaked;
/// @notice Total rewards distributed
uint256 public totalRewardsDistributed;
/// @notice Rewards pool balance
uint256 public rewardsPool;
// ============ Events ============
event Staked(address indexed user, uint256 stakeId, uint256 amount, uint256 lockPeriod, uint256 apr);
event Unstaked(address indexed user, uint256 stakeId, uint256 amount, uint256 rewards);
event RewardsClaimed(address indexed user, uint256 stakeId, uint256 rewards);
event TierUpdated(uint256 lockPeriod, uint256 apr, uint256 multiplier, bool active);
event RewardsDeposited(address indexed depositor, uint256 amount);
event EmergencyWithdraw(address indexed user, uint256 stakeId, uint256 amount);
// ============ Constructor ============
constructor(address _ambxToken, address admin) {
require(_ambxToken != address(0), "Invalid token address");
require(admin != address(0), "Invalid admin address");
ambxToken = IERC20(_ambxToken);
_grantRole(DEFAULT_ADMIN_ROLE, admin);
_grantRole(ADMIN_ROLE, admin);
_grantRole(OPERATOR_ROLE, admin);
// Initialize default staking tiers
_initializeTiers();
}
// ============ Internal Initialization ============
function _initializeTiers() internal {
// 30 days: 5% APY
stakingTiers[30 days] = StakingTier({
lockPeriod: 30 days,
apr: 500, // 5%
multiplier: 100, // 1.0x
active: true
});
// 90 days: 8% APY
stakingTiers[90 days] = StakingTier({
lockPeriod: 90 days,
apr: 800, // 8%
multiplier: 160, // 1.6x
active: true
});
// 180 days: 12% APY
stakingTiers[180 days] = StakingTier({
lockPeriod: 180 days,
apr: 1200, // 12%
multiplier: 240, // 2.4x
active: true
});
// 365 days: 15% APY
stakingTiers[365 days] = StakingTier({
lockPeriod: 365 days,
apr: 1500, // 15%
multiplier: 300, // 3.0x
active: true
});
}
// ============ Staking Functions ============
/**
* @notice Stake AMBX tokens for a specific lock period
* @param amount Amount of AMBX to stake
* @param lockPeriod Lock period (must match a tier: 30, 90, 180, or 365 days)
*/
function stake(uint256 amount, uint256 lockPeriod) external nonReentrant whenNotPaused {
require(amount > 0, "Amount must be positive");
StakingTier memory tier = stakingTiers[lockPeriod];
require(tier.active, "Invalid or inactive tier");
// Transfer tokens from user
ambxToken.safeTransferFrom(msg.sender, address(this), amount);
// Create stake
userStakes[msg.sender].push(Stake({
amount: amount,
startTime: block.timestamp,
lockPeriod: lockPeriod,
apr: tier.apr,
rewardsClaimed: 0,
active: true
}));
totalStaked += amount;
uint256 stakeId = userStakes[msg.sender].length - 1;
emit Staked(msg.sender, stakeId, amount, lockPeriod, tier.apr);
}
/**
* @notice Unstake tokens and claim rewards
* @param stakeId Index of the stake to unstake
*/
function unstake(uint256 stakeId) external nonReentrant {
require(stakeId < userStakes[msg.sender].length, "Invalid stake ID");
Stake storage userStake = userStakes[msg.sender][stakeId];
require(userStake.active, "Stake not active");
require(block.timestamp >= userStake.startTime + userStake.lockPeriod, "Lock period not ended");
uint256 rewards = _calculateRewards(userStake);
uint256 totalAmount = userStake.amount + rewards;
// Mark as inactive
userStake.active = false;
totalStaked -= userStake.amount;
// Update rewards tracking
if (rewards > 0) {
require(rewardsPool >= rewards, "Insufficient rewards pool");
rewardsPool -= rewards;
totalRewardsDistributed += rewards;
}
// Transfer tokens + rewards
ambxToken.safeTransfer(msg.sender, totalAmount);
emit Unstaked(msg.sender, stakeId, userStake.amount, rewards);
}
/**
* @notice Claim rewards without unstaking
* @param stakeId Index of the stake
*/
function claimRewards(uint256 stakeId) external nonReentrant {
require(stakeId < userStakes[msg.sender].length, "Invalid stake ID");
Stake storage userStake = userStakes[msg.sender][stakeId];
require(userStake.active, "Stake not active");
uint256 rewards = _calculateRewards(userStake);
require(rewards > 0, "No rewards available");
require(rewardsPool >= rewards, "Insufficient rewards pool");
userStake.rewardsClaimed += rewards;
rewardsPool -= rewards;
totalRewardsDistributed += rewards;
ambxToken.safeTransfer(msg.sender, rewards);
emit RewardsClaimed(msg.sender, stakeId, rewards);
}
/**
* @notice Emergency unstake without rewards (penalty)
* @param stakeId Index of the stake
*/
function emergencyUnstake(uint256 stakeId) external nonReentrant {
require(stakeId < userStakes[msg.sender].length, "Invalid stake ID");
Stake storage userStake = userStakes[msg.sender][stakeId];
require(userStake.active, "Stake not active");
uint256 amount = userStake.amount;
userStake.active = false;
totalStaked -= amount;
// Return principal only (no rewards)
ambxToken.safeTransfer(msg.sender, amount);
emit EmergencyWithdraw(msg.sender, stakeId, amount);
}
// ============ View Functions ============
/**
* @notice Calculate pending rewards for a stake
*/
function pendingRewards(address user, uint256 stakeId) external view returns (uint256) {
require(stakeId < userStakes[user].length, "Invalid stake ID");
Stake memory userStake = userStakes[user][stakeId];
if (!userStake.active) return 0;
return _calculateRewards(userStake);
}
/**
* @notice Get all stakes for a user
*/
function getUserStakes(address user) external view returns (Stake[] memory) {
return userStakes[user];
}
/**
* @notice Get stake count for user
*/
function getStakeCount(address user) external view returns (uint256) {
return userStakes[user].length;
}
/**
* @notice Get total staked by user (active stakes only)
*/
function getUserTotalStaked(address user) external view returns (uint256) {
uint256 total = 0;
Stake[] memory stakes = userStakes[user];
for (uint256 i = 0; i < stakes.length; i++) {
if (stakes[i].active) {
total += stakes[i].amount;
}
}
return total;
}
// ============ Internal Functions ============
function _calculateRewards(Stake memory userStake) internal view returns (uint256) {
if (!userStake.active) return 0;
uint256 timeStaked = block.timestamp - userStake.startTime;
if (timeStaked == 0) return 0;
// rewards = principal * apr * time / (BASIS_POINTS * SECONDS_PER_YEAR)
uint256 rewards = (userStake.amount * userStake.apr * timeStaked) / (BASIS_POINTS * SECONDS_PER_YEAR);
// Subtract already claimed rewards
if (rewards > userStake.rewardsClaimed) {
return rewards - userStake.rewardsClaimed;
}
return 0;
}
// ============ Admin Functions ============
/**
* @notice Deposit rewards into the pool
*/
function depositRewards(uint256 amount) external onlyRole(ADMIN_ROLE) {
require(amount > 0, "Amount must be positive");
ambxToken.safeTransferFrom(msg.sender, address(this), amount);
rewardsPool += amount;
emit RewardsDeposited(msg.sender, amount);
}
/**
* @notice Update staking tier parameters
*/
function updateTier(uint256 lockPeriod, uint256 apr, uint256 multiplier, bool active)
external
onlyRole(ADMIN_ROLE)
{
require(apr <= 10000, "APR too high"); // Max 100%
stakingTiers[lockPeriod] = StakingTier({
lockPeriod: lockPeriod,
apr: apr,
multiplier: multiplier,
active: active
});
emit TierUpdated(lockPeriod, apr, multiplier, active);
}
/**
* @notice Pause staking
*/
function pause() external onlyRole(ADMIN_ROLE) {
_pause();
}
/**
* @notice Unpause staking
*/
function unpause() external onlyRole(ADMIN_ROLE) {
_unpause();
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (access/AccessControl.sol)
pragma solidity ^0.8.20;
import {IAccessControl} from "./IAccessControl.sol";
import {Context} from "../utils/Context.sol";
import {IERC165, ERC165} from "../utils/introspection/ERC165.sol";
/**
* @dev Contract module that allows children to implement role-based access
* control mechanisms. This is a lightweight version that doesn't allow enumerating role
* members except through off-chain means by accessing the contract event logs. Some
* applications may benefit from on-chain enumerability, for those cases see
* {AccessControlEnumerable}.
*
* Roles are referred to by their `bytes32` identifier. These should be exposed
* in the external API and be unique. The best way to achieve this is by
* using `public constant` hash digests:
*
* ```solidity
* bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
* ```
*
* Roles can be used to represent a set of permissions. To restrict access to a
* function call, use {hasRole}:
*
* ```solidity
* function foo() public {
* require(hasRole(MY_ROLE, msg.sender));
* ...
* }
* ```
*
* Roles can be granted and revoked dynamically via the {grantRole} and
* {revokeRole} functions. Each role has an associated admin role, and only
* accounts that have a role's admin role can call {grantRole} and {revokeRole}.
*
* By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
* that only accounts with this role will be able to grant or revoke other
* roles. More complex role relationships can be created by using
* {_setRoleAdmin}.
*
* WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
* grant and revoke this role. Extra precautions should be taken to secure
* accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}
* to enforce additional security measures for this role.
*/
abstract contract AccessControl is Context, IAccessControl, ERC165 {
struct RoleData {
mapping(address account => bool) hasRole;
bytes32 adminRole;
}
mapping(bytes32 role => RoleData) private _roles;
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
/**
* @dev Modifier that checks that an account has a specific role. Reverts
* with an {AccessControlUnauthorizedAccount} error including the required role.
*/
modifier onlyRole(bytes32 role) {
_checkRole(role);
_;
}
/// @inheritdoc IERC165
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
}
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) public view virtual returns (bool) {
return _roles[role].hasRole[account];
}
/**
* @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()`
* is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier.
*/
function _checkRole(bytes32 role) internal view virtual {
_checkRole(role, _msgSender());
}
/**
* @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account`
* is missing `role`.
*/
function _checkRole(bytes32 role, address account) internal view virtual {
if (!hasRole(role, account)) {
revert AccessControlUnauthorizedAccount(account, role);
}
}
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) public view virtual returns (bytes32) {
return _roles[role].adminRole;
}
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*
* May emit a {RoleGranted} event.
*/
function grantRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
_grantRole(role, account);
}
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*
* May emit a {RoleRevoked} event.
*/
function revokeRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
_revokeRole(role, account);
}
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been revoked `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `callerConfirmation`.
*
* May emit a {RoleRevoked} event.
*/
function renounceRole(bytes32 role, address callerConfirmation) public virtual {
if (callerConfirmation != _msgSender()) {
revert AccessControlBadConfirmation();
}
_revokeRole(role, callerConfirmation);
}
/**
* @dev Sets `adminRole` as ``role``'s admin role.
*
* Emits a {RoleAdminChanged} event.
*/
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
bytes32 previousAdminRole = getRoleAdmin(role);
_roles[role].adminRole = adminRole;
emit RoleAdminChanged(role, previousAdminRole, adminRole);
}
/**
* @dev Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted.
*
* Internal function without access restriction.
*
* May emit a {RoleGranted} event.
*/
function _grantRole(bytes32 role, address account) internal virtual returns (bool) {
if (!hasRole(role, account)) {
_roles[role].hasRole[account] = true;
emit RoleGranted(role, account, _msgSender());
return true;
} else {
return false;
}
}
/**
* @dev Attempts to revoke `role` from `account` and returns a boolean indicating if `role` was revoked.
*
* Internal function without access restriction.
*
* May emit a {RoleRevoked} event.
*/
function _revokeRole(bytes32 role, address account) internal virtual returns (bool) {
if (hasRole(role, account)) {
_roles[role].hasRole[account] = false;
emit RoleRevoked(role, account, _msgSender());
return true;
} else {
return false;
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (access/IAccessControl.sol)
pragma solidity >=0.8.4;
/**
* @dev External interface of AccessControl declared to support ERC-165 detection.
*/
interface IAccessControl {
/**
* @dev The `account` is missing a role.
*/
error AccessControlUnauthorizedAccount(address account, bytes32 neededRole);
/**
* @dev The caller of a function is not the expected one.
*
* NOTE: Don't confuse with {AccessControlUnauthorizedAccount}.
*/
error AccessControlBadConfirmation();
/**
* @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
*
* `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
* {RoleAdminChanged} not being emitted to signal this.
*/
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
/**
* @dev Emitted when `account` is granted `role`.
*
* `sender` is the account that originated the contract call. This account bears the admin role (for the granted role).
* Expected in cases where the role was granted using the internal {AccessControl-_grantRole}.
*/
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Emitted when `account` is revoked `role`.
*
* `sender` is the account that originated the contract call:
* - if using `revokeRole`, it is the admin role bearer
* - if using `renounceRole`, it is the role bearer (i.e. `account`)
*/
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) external view returns (bool);
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {AccessControl-_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) external view returns (bytes32);
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function grantRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function revokeRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been granted `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `callerConfirmation`.
*/
function renounceRole(bytes32 role, address callerConfirmation) external;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC1363.sol)
pragma solidity >=0.6.2;
import {IERC20} from "./IERC20.sol";
import {IERC165} from "./IERC165.sol";
/**
* @title IERC1363
* @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363].
*
* Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract
* after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction.
*/
interface IERC1363 is IERC20, IERC165 {
/*
* Note: the ERC-165 identifier for this interface is 0xb0202a11.
* 0xb0202a11 ===
* bytes4(keccak256('transferAndCall(address,uint256)')) ^
* bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^
* bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^
* bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^
* bytes4(keccak256('approveAndCall(address,uint256)')) ^
* bytes4(keccak256('approveAndCall(address,uint256,bytes)'))
*/
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferAndCall(address to, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @param data Additional data with no specified format, sent in call to `to`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param from The address which you want to send tokens from.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferFromAndCall(address from, address to, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param from The address which you want to send tokens from.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @param data Additional data with no specified format, sent in call to `to`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.
* @param spender The address which will spend the funds.
* @param value The amount of tokens to be spent.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function approveAndCall(address spender, uint256 value) external returns (bool);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.
* @param spender The address which will spend the funds.
* @param value The amount of tokens to be spent.
* @param data Additional data with no specified format, sent in call to `spender`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC165.sol)
pragma solidity >=0.4.16;
import {IERC165} from "../utils/introspection/IERC165.sol";// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC20.sol)
pragma solidity >=0.4.16;
import {IERC20} from "../token/ERC20/IERC20.sol";// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/IERC20.sol)
pragma solidity >=0.4.16;
/**
* @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);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.3.0) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.20;
import {IERC20} from "../IERC20.sol";
import {IERC1363} from "../../../interfaces/IERC1363.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC-20 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 {
/**
* @dev An operation with an ERC-20 token failed.
*/
error SafeERC20FailedOperation(address token);
/**
* @dev Indicates a failed `decreaseAllowance` request.
*/
error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);
/**
* @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));
}
/**
* @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
* calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
*/
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));
}
/**
* @dev Variant of {safeTransfer} that returns a bool instead of reverting if the operation is not successful.
*/
function trySafeTransfer(IERC20 token, address to, uint256 value) internal returns (bool) {
return _callOptionalReturnBool(token, abi.encodeCall(token.transfer, (to, value)));
}
/**
* @dev Variant of {safeTransferFrom} that returns a bool instead of reverting if the operation is not successful.
*/
function trySafeTransferFrom(IERC20 token, address from, address to, uint256 value) internal returns (bool) {
return _callOptionalReturnBool(token, abi.encodeCall(token.transferFrom, (from, to, value)));
}
/**
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*
* IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client"
* smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using
* this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract
* that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.
*/
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
forceApprove(token, spender, oldAllowance + value);
}
/**
* @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no
* value, non-reverting calls are assumed to be successful.
*
* IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client"
* smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using
* this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract
* that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.
*/
function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {
unchecked {
uint256 currentAllowance = token.allowance(address(this), spender);
if (currentAllowance < requestedDecrease) {
revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);
}
forceApprove(token, spender, currentAllowance - requestedDecrease);
}
}
/**
* @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
* to be set to zero before setting it to a non-zero value, such as USDT.
*
* NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function
* only sets the "standard" allowance. Any temporary allowance will remain active, in addition to the value being
* set here.
*/
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));
_callOptionalReturn(token, approvalCall);
}
}
/**
* @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no
* code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* Reverts if the returned value is other than `true`.
*/
function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {
if (to.code.length == 0) {
safeTransfer(token, to, value);
} else if (!token.transferAndCall(to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target
* has no code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* Reverts if the returned value is other than `true`.
*/
function transferFromAndCallRelaxed(
IERC1363 token,
address from,
address to,
uint256 value,
bytes memory data
) internal {
if (to.code.length == 0) {
safeTransferFrom(token, from, to, value);
} else if (!token.transferFromAndCall(from, to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no
* code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}.
* Opposedly, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall}
* once without retrying, and relies on the returned value to be true.
*
* Reverts if the returned value is other than `true`.
*/
function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {
if (to.code.length == 0) {
forceApprove(token, to, value);
} else if (!token.approveAndCall(to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @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).
*
* This is a variant of {_callOptionalReturnBool} that reverts if call fails to meet the requirements.
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
uint256 returnSize;
uint256 returnValue;
assembly ("memory-safe") {
let success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)
// bubble errors
if iszero(success) {
let ptr := mload(0x40)
returndatacopy(ptr, 0, returndatasize())
revert(ptr, returndatasize())
}
returnSize := returndatasize()
returnValue := mload(0)
}
if (returnSize == 0 ? address(token).code.length == 0 : returnValue != 1) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @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).
*
* This is a variant of {_callOptionalReturn} that silently catches all reverts and returns a bool instead.
*/
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
bool success;
uint256 returnSize;
uint256 returnValue;
assembly ("memory-safe") {
success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)
returnSize := returndatasize()
returnValue := mload(0)
}
return success && (returnSize == 0 ? address(token).code.length > 0 : returnValue == 1);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/ERC165.sol)
pragma solidity ^0.8.20;
import {IERC165} from "./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC-165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*/
abstract contract ERC165 is IERC165 {
/// @inheritdoc IERC165
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/IERC165.sol)
pragma solidity >=0.4.16;
/**
* @dev Interface of the ERC-165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[ERC].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.3.0) (utils/Pausable.sol)
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
/**
* @dev Contract module which allows children to implement an emergency stop
* mechanism that can be triggered by an authorized account.
*
* This module is used through inheritance. It will make available the
* modifiers `whenNotPaused` and `whenPaused`, which can be applied to
* the functions of your contract. Note that they will not be pausable by
* simply including this module, only once the modifiers are put in place.
*/
abstract contract Pausable is Context {
bool private _paused;
/**
* @dev Emitted when the pause is triggered by `account`.
*/
event Paused(address account);
/**
* @dev Emitted when the pause is lifted by `account`.
*/
event Unpaused(address account);
/**
* @dev The operation failed because the contract is paused.
*/
error EnforcedPause();
/**
* @dev The operation failed because the contract is not paused.
*/
error ExpectedPause();
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*
* Requirements:
*
* - The contract must not be paused.
*/
modifier whenNotPaused() {
_requireNotPaused();
_;
}
/**
* @dev Modifier to make a function callable only when the contract is paused.
*
* Requirements:
*
* - The contract must be paused.
*/
modifier whenPaused() {
_requirePaused();
_;
}
/**
* @dev Returns true if the contract is paused, and false otherwise.
*/
function paused() public view virtual returns (bool) {
return _paused;
}
/**
* @dev Throws if the contract is paused.
*/
function _requireNotPaused() internal view virtual {
if (paused()) {
revert EnforcedPause();
}
}
/**
* @dev Throws if the contract is not paused.
*/
function _requirePaused() internal view virtual {
if (!paused()) {
revert ExpectedPause();
}
}
/**
* @dev Triggers stopped state.
*
* Requirements:
*
* - The contract must not be paused.
*/
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
/**
* @dev Returns to normal state.
*
* Requirements:
*
* - The contract must be paused.
*/
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/ReentrancyGuard.sol)
pragma solidity ^0.8.20;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If EIP-1153 (transient storage) is available on the chain you're deploying at,
* consider using {ReentrancyGuardTransient} instead.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant NOT_ENTERED = 1;
uint256 private constant ENTERED = 2;
uint256 private _status;
/**
* @dev Unauthorized reentrant call.
*/
error ReentrancyGuardReentrantCall();
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 making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
// On the first call to nonReentrant, _status will be NOT_ENTERED
if (_status == ENTERED) {
revert ReentrancyGuardReentrantCall();
}
// Any calls to nonReentrant after this point will fail
_status = ENTERED;
}
function _nonReentrantAfter() private {
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = NOT_ENTERED;
}
/**
* @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
* `nonReentrant` function in the call stack.
*/
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == ENTERED;
}
}{
"optimizer": {
"enabled": true,
"runs": 200
},
"evmVersion": "paris",
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_ambxToken","type":"address"},{"internalType":"address","name":"admin","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AccessControlBadConfirmation","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"neededRole","type":"bytes32"}],"name":"AccessControlUnauthorizedAccount","type":"error"},{"inputs":[],"name":"EnforcedPause","type":"error"},{"inputs":[],"name":"ExpectedPause","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"stakeId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"EmergencyWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"stakeId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rewards","type":"uint256"}],"name":"RewardsClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"depositor","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RewardsDeposited","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"stakeId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lockPeriod","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"apr","type":"uint256"}],"name":"Staked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"lockPeriod","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"apr","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"multiplier","type":"uint256"},{"indexed":false,"internalType":"bool","name":"active","type":"bool"}],"name":"TierUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"stakeId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rewards","type":"uint256"}],"name":"Unstaked","type":"event"},{"inputs":[],"name":"ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BASIS_POINTS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OPERATOR_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SECONDS_PER_YEAR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ambxToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"stakeId","type":"uint256"}],"name":"claimRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"depositRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"stakeId","type":"uint256"}],"name":"emergencyUnstake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getStakeCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getUserStakes","outputs":[{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"lockPeriod","type":"uint256"},{"internalType":"uint256","name":"apr","type":"uint256"},{"internalType":"uint256","name":"rewardsClaimed","type":"uint256"},{"internalType":"bool","name":"active","type":"bool"}],"internalType":"struct AMBXStaking.Stake[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getUserTotalStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"stakeId","type":"uint256"}],"name":"pendingRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"callerConfirmation","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardsPool","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"lockPeriod","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"stakingTiers","outputs":[{"internalType":"uint256","name":"lockPeriod","type":"uint256"},{"internalType":"uint256","name":"apr","type":"uint256"},{"internalType":"uint256","name":"multiplier","type":"uint256"},{"internalType":"bool","name":"active","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalRewardsDistributed","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":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"stakeId","type":"uint256"}],"name":"unstake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"lockPeriod","type":"uint256"},{"internalType":"uint256","name":"apr","type":"uint256"},{"internalType":"uint256","name":"multiplier","type":"uint256"},{"internalType":"bool","name":"active","type":"bool"}],"name":"updateTier","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"userStakes","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"lockPeriod","type":"uint256"},{"internalType":"uint256","name":"apr","type":"uint256"},{"internalType":"uint256","name":"rewardsClaimed","type":"uint256"},{"internalType":"bool","name":"active","type":"bool"}],"stateMutability":"view","type":"function"}]Contract Creation Code
60a06040523480156200001157600080fd5b5060405162001fdc38038062001fdc833981016040819052620000349162000565565b600180556001600160a01b038216620000945760405162461bcd60e51b815260206004820152601560248201527f496e76616c696420746f6b656e2061646472657373000000000000000000000060448201526064015b60405180910390fd5b6001600160a01b038116620000ec5760405162461bcd60e51b815260206004820152601560248201527f496e76616c69642061646d696e2061646472657373000000000000000000000060448201526064016200008b565b6001600160a01b0382166080526200010660008262000499565b50620001337fa49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c217758262000499565b50620001607f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b9298262000499565b5062000491604080516080808201835262278d008083526101f460208085019182526064858701908152600160608088018281526000968752600480865298517f5564a3699837f937070bc8e1a858506e72778e568c12590eed67a771b908e2235594517f5564a3699837f937070bc8e1a858506e72778e568c12590eed67a771b908e2245591517f5564a3699837f937070bc8e1a858506e72778e568c12590eed67a771b908e2255592517f5564a3699837f937070bc8e1a858506e72778e568c12590eed67a771b908e226805491151560ff19928316179055875180870189526276a70080825261032082860190815260a0838c019081528386018881529289528a875292517f3fed37f7d98193d2657b011eb0a3eec5f7221e6290af9fcd81f4c04fccd6843d55517f3fed37f7d98193d2657b011eb0a3eec5f7221e6290af9fcd81f4c04fccd6843e5590517f3fed37f7d98193d2657b011eb0a3eec5f7221e6290af9fcd81f4c04fccd6843f55517f3fed37f7d98193d2657b011eb0a3eec5f7221e6290af9fcd81f4c04fccd6844080549115159183169190911790558751808701895262ed4e008082526104b082860190815260f0838c019081528386018881529289528a875292517f745bcf281519ca17f064b0f61aac5766ee74f04b012d25a38690d2e3b51e860955517f745bcf281519ca17f064b0f61aac5766ee74f04b012d25a38690d2e3b51e860a5590517f745bcf281519ca17f064b0f61aac5766ee74f04b012d25a38690d2e3b51e860b55517f745bcf281519ca17f064b0f61aac5766ee74f04b012d25a38690d2e3b51e860c8054911515918316919091179055875195860188526301e133808087526105dc87850190815261012c998801998a5292870194855290945294905291517f97b3babdc81bea0ad63eac221e7a5d9bc79ed7f55e35cb889964bd67dc5163945591517f97b3babdc81bea0ad63eac221e7a5d9bc79ed7f55e35cb889964bd67dc5163955591517f97b3babdc81bea0ad63eac221e7a5d9bc79ed7f55e35cb889964bd67dc5163965590517f97b3babdc81bea0ad63eac221e7a5d9bc79ed7f55e35cb889964bd67dc516397805491151591909216179055565b50506200059d565b6000828152602081815260408083206001600160a01b038516845290915281205460ff166200053e576000838152602081815260408083206001600160a01b03861684529091529020805460ff19166001179055620004f53390565b6001600160a01b0316826001600160a01b0316847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a450600162000542565b5060005b92915050565b80516001600160a01b03811681146200056057600080fd5b919050565b600080604083850312156200057957600080fd5b620005848362000548565b9150620005946020840162000548565b90509250929050565b608051611a00620005dc600039600081816103670152818161059c0152818161081501528181610a7e01528181610e7401526110fb0152611a006000f3fe608060405234801561001057600080fd5b50600436106101da5760003560e01c8063842e298111610104578063c621f94c116100a2578063e1f1c4a711610071578063e1f1c4a71461048c578063e6a69ab814610495578063ee172546146104a0578063f5b541a6146104a957600080fd5b8063c621f94c146103e3578063cf57ee69146103f6578063d50267ee1461041f578063d547741f1461047957600080fd5b806391d14854116100de57806391d1485414610347578063a217fddf1461035a578063af70db9014610362578063b5d5b5fa146103a157600080fd5b8063842e29811461030c5780638456cb591461032c5780638bdf67f21461033457600080fd5b806336568abe1161017c5780636e2f16961161014b5780636e2f1696146102c857806375b238fc146102db5780637b0472f0146102f0578063817b1cd21461030357600080fd5b806336568abe1461028f5780633f4ba83a146102a25780635c975abb146102aa5780636099ecb2146102b557600080fd5b80630962ef79116101b85780630962ef7914610233578063248a9ca3146102465780632e17de78146102695780632f2ff15d1461027c57600080fd5b8063012ce501146101df57806301ffc9a7146101f45780630359fea91461021c575b600080fd5b6101f26101ed3660046116f9565b6104d0565b005b610207610202366004611712565b61060d565b60405190151581526020015b60405180910390f35b61022560075481565b604051908152602001610213565b6101f26102413660046116f9565b610644565b6102256102543660046116f9565b60009081526020819052604090206001015490565b6101f26102773660046116f9565b610874565b6101f261028a36600461175f565b610af6565b6101f261029d36600461175f565b610b21565b6101f2610b59565b60025460ff16610207565b6102256102c336600461178b565b610b79565b6102256102d63660046117b5565b610c58565b6102256000805160206119ab83398151915281565b6101f26102fe3660046117d0565b610d79565b61022560055481565b61031f61031a3660046117b5565b610fbc565b60405161021391906117f2565b6101f261106c565b6101f26103423660046116f9565b61108c565b61020761035536600461175f565b611173565b610225600081565b6103897f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610213565b6103b46103af36600461178b565b61119c565b6040805196875260208701959095529385019290925260608401526080830152151560a082015260c001610213565b6101f26103f136600461186c565b6111f3565b6102256104043660046117b5565b6001600160a01b031660009081526003602052604090205490565b61045761042d3660046116f9565b60046020526000908152604090208054600182015460028301546003909301549192909160ff1684565b6040805194855260208501939093529183015215156060820152608001610213565b6101f261048736600461175f565b6112f2565b61022561271081565b6102256301e1338081565b61022560065481565b6102257f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b92981565b6104d8611317565b33600090815260036020526040902054811061050f5760405162461bcd60e51b8152600401610506906118b2565b60405180910390fd5b336000908152600360205260408120805483908110610530576105306118dc565b60009182526020909120600690910201600581015490915060ff166105675760405162461bcd60e51b8152600401610506906118f2565b80546005808301805460ff191690558054829190600090610589908490611932565b909155506105c390506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163383611341565b604080518481526020810183905233917fbb757047c2b5f3974fe26b7c10f732e7bce710b0952a71082702781e62ae059591015b60405180910390a2505061060a60018055565b50565b60006001600160e01b03198216637965db0b60e01b148061063e57506301ffc9a760e01b6001600160e01b03198316145b92915050565b61064c611317565b33600090815260036020526040902054811061067a5760405162461bcd60e51b8152600401610506906118b2565b33600090815260036020526040812080548390811061069b5761069b6118dc565b60009182526020909120600690910201600581015490915060ff166106d25760405162461bcd60e51b8152600401610506906118f2565b6040805160c08101825282548152600183015460208201526002830154918101919091526003820154606082015260048201546080820152600582015460ff16151560a0820152600090610725906113a0565b90506000811161076e5760405162461bcd60e51b81526020600482015260146024820152734e6f207265776172647320617661696c61626c6560601b6044820152606401610506565b8060075410156107bc5760405162461bcd60e51b8152602060048201526019602482015278125b9cdd59999a58da595b9d081c995dd85c991cc81c1bdbdb603a1b6044820152606401610506565b808260040160008282546107d09190611945565b9250508190555080600760008282546107e99190611932565b9250508190555080600660008282546108029190611945565b9091555061083c90506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163383611341565b604080518481526020810183905233917fdacbdde355ba930696a362ea6738feb9f8bd52dfb3d81947558fd3217e23e32591016105f7565b61087c611317565b3360009081526003602052604090205481106108aa5760405162461bcd60e51b8152600401610506906118b2565b3360009081526003602052604081208054839081106108cb576108cb6118dc565b60009182526020909120600690910201600581015490915060ff166109025760405162461bcd60e51b8152600401610506906118f2565b806002015481600101546109169190611945565b42101561095d5760405162461bcd60e51b8152602060048201526015602482015274131bd8dac81c195c9a5bd9081b9bdd08195b991959605a1b6044820152606401610506565b6040805160c08101825282548152600183015460208201526002830154918101919091526003820154606082015260048201546080820152600582015460ff16151560a08201526000906109b0906113a0565b905060008183600001546109c49190611945565b6005808501805460ff1916905584548154929350916000906109e7908490611932565b90915550508115610a7157816007541015610a405760405162461bcd60e51b8152602060048201526019602482015278125b9cdd59999a58da595b9d081c995dd85c991cc81c1bdbdb603a1b6044820152606401610506565b8160076000828254610a529190611932565b925050819055508160066000828254610a6b9190611945565b90915550505b610aa56001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163383611341565b8254604080518681526020810192909252810183905233907f204fccf0d92ed8d48f204adb39b2e81e92bad0dedb93f5716ca9478cfb57de009060600160405180910390a250505061060a60018055565b600082815260208190526040902060010154610b1181611437565b610b1b8383611441565b50505050565b6001600160a01b0381163314610b4a5760405163334bd91960e11b815260040160405180910390fd5b610b5482826114d3565b505050565b6000805160206119ab833981519152610b7181611437565b61060a61153e565b6001600160a01b0382166000908152600360205260408120548210610bb05760405162461bcd60e51b8152600401610506906118b2565b6001600160a01b0383166000908152600360205260408120805484908110610bda57610bda6118dc565b60009182526020918290206040805160c081018252600690930290910180548352600181015493830193909352600283015490820152600382015460608201526004820154608082015260059091015460ff16151560a08201819052909150610c4757600091505061063e565b610c50816113a0565b949350505050565b6001600160a01b0381166000908152600360209081526040808320805482518185028101850190935280835284938493929190849084015b82821015610cfd5760008481526020908190206040805160c08101825260068602909201805483526001808201548486015260028201549284019290925260038101546060840152600481015460808401526005015460ff16151560a08301529083529092019101610c90565b50505050905060005b8151811015610d7057818181518110610d2157610d216118dc565b602002602001015160a0015115610d5e57818181518110610d4457610d446118dc565b60200260200101516000015183610d5b9190611945565b92505b80610d6881611958565b915050610d06565b50909392505050565b610d81611317565b610d89611590565b60008211610dd35760405162461bcd60e51b8152602060048201526017602482015276416d6f756e74206d75737420626520706f73697469766560481b6044820152606401610506565b60008181526004602090815260409182902082516080810184528154815260018201549281019290925260028101549282019290925260039091015460ff16151560608201819052610e675760405162461bcd60e51b815260206004820152601860248201527f496e76616c6964206f7220696e616374697665207469657200000000000000006044820152606401610506565b610e9c6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163330866115b6565b336000908152600360208181526040808420815160c08101835288815242818501908152928101888152878501516060830190815260808301888152600160a0850181815286548083018855968b52978a20945160069096029094019485559451928401929092555160028301555193810193909355516004830155516005918201805460ff19169115159190911790558054859290610f3d908490611945565b909155505033600090815260036020526040812054610f5e90600190611932565b602080840151604080518481529283018890528201869052606082015290915033907f9cfd25589d1eb8ad71e342a86a8524e83522e3936c0803048c08f6d9ad974f409060800160405180910390a25050610fb860018055565b5050565b6001600160a01b0381166000908152600360209081526040808320805482518185028101850190935280835260609492939192909184015b828210156110615760008481526020908190206040805160c08101825260068602909201805483526001808201548486015260028201549284019290925260038101546060840152600481015460808401526005015460ff16151560a08301529083529092019101610ff4565b505050509050919050565b6000805160206119ab83398151915261108481611437565b61060a6115ef565b6000805160206119ab8339815191526110a481611437565b600082116110ee5760405162461bcd60e51b8152602060048201526017602482015276416d6f756e74206d75737420626520706f73697469766560481b6044820152606401610506565b6111236001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163330856115b6565b81600760008282546111359190611945565b909155505060405182815233907fb8b27d0db504fa5d914f1fd330347096e88d5ff94b6c612d32797e7c12a8f66f9060200160405180910390a25050565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b600360205281600052604060002081815481106111b857600080fd5b600091825260209091206006909102018054600182015460028301546003840154600485015460059095015493965091945092909160ff1686565b6000805160206119ab83398151915261120b81611437565b61271084111561124c5760405162461bcd60e51b815260206004820152600c60248201526b082a0a440e8dede40d0d2ced60a31b6044820152606401610506565b60408051608080820183528782526020808301888152838501888152871515606080870182815260008e81526004875289902097518855935160018801559151600287015591516003909501805460ff19169515159590951790945584518a8152918201899052938101879052918201929092527f05d4036401e9924f65639a62f654cc632427f9aa354735867985d233ed2b02e7910160405180910390a15050505050565b60008281526020819052604090206001015461130d81611437565b610b1b83836114d3565b60026001540361133a57604051633ee5aeb560e01b815260040160405180910390fd5b6002600155565b6040516001600160a01b03838116602483015260448201839052610b5491859182169063a9059cbb906064015b604051602081830303815290604052915060e01b6020820180516001600160e01b03838183161783525050505061162c565b60008160a001516113b357506000919050565b60008260200151426113c59190611932565b9050806000036113d85750600092915050565b60006113ea6301e13380612710611971565b6060850151855184916113fc91611971565b6114069190611971565b6114109190611988565b9050836080015181111561142d576080840151610c509082611932565b5060009392505050565b61060a813361169d565b600061144d8383611173565b6114cb576000838152602081815260408083206001600160a01b03861684529091529020805460ff191660011790556114833390565b6001600160a01b0316826001600160a01b0316847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a450600161063e565b50600061063e565b60006114df8383611173565b156114cb576000838152602081815260408083206001600160a01b0386168085529252808320805460ff1916905551339286917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a450600161063e565b6115466116d6565b6002805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b60025460ff16156115b45760405163d93c066560e01b815260040160405180910390fd5b565b6040516001600160a01b038481166024830152838116604483015260648201839052610b1b9186918216906323b872dd9060840161136e565b6115f7611590565b6002805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586115733390565b600080602060008451602086016000885af18061164f576040513d6000823e3d81fd5b50506000513d91508115611667578060011415611674565b6001600160a01b0384163b155b15610b1b57604051635274afe760e01b81526001600160a01b0385166004820152602401610506565b6116a78282611173565b610fb85760405163e2517d3f60e01b81526001600160a01b038216600482015260248101839052604401610506565b60025460ff166115b457604051638dfc202b60e01b815260040160405180910390fd5b60006020828403121561170b57600080fd5b5035919050565b60006020828403121561172457600080fd5b81356001600160e01b03198116811461173c57600080fd5b9392505050565b80356001600160a01b038116811461175a57600080fd5b919050565b6000806040838503121561177257600080fd5b8235915061178260208401611743565b90509250929050565b6000806040838503121561179e57600080fd5b6117a783611743565b946020939093013593505050565b6000602082840312156117c757600080fd5b61173c82611743565b600080604083850312156117e357600080fd5b50508035926020909101359150565b602080825282518282018190526000919060409081850190868401855b8281101561185f5781518051855286810151878601528581015186860152606080820151908601526080808201519086015260a09081015115159085015260c0909301929085019060010161180f565b5091979650505050505050565b6000806000806080858703121561188257600080fd5b843593506020850135925060408501359150606085013580151581146118a757600080fd5b939692955090935050565b60208082526010908201526f125b9d985b1a59081cdd185ad948125160821b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b60208082526010908201526f5374616b65206e6f742061637469766560801b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b8181038181111561063e5761063e61191c565b8082018082111561063e5761063e61191c565b60006001820161196a5761196a61191c565b5060010190565b808202811582820484141761063e5761063e61191c565b6000826119a557634e487b7160e01b600052601260045260246000fd5b50049056fea49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c21775a26469706673582212209be5c8ccb49442a980cd4d2ec491b531513dc0639b4e483e2dd3685aa737c74264736f6c63430008140033000000000000000000000000b523a5381200650b41ac47868b25f03e8b95b9400000000000000000000000005ec862ddcedf71ba0022ed14cb58efaba55bdd9a
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101da5760003560e01c8063842e298111610104578063c621f94c116100a2578063e1f1c4a711610071578063e1f1c4a71461048c578063e6a69ab814610495578063ee172546146104a0578063f5b541a6146104a957600080fd5b8063c621f94c146103e3578063cf57ee69146103f6578063d50267ee1461041f578063d547741f1461047957600080fd5b806391d14854116100de57806391d1485414610347578063a217fddf1461035a578063af70db9014610362578063b5d5b5fa146103a157600080fd5b8063842e29811461030c5780638456cb591461032c5780638bdf67f21461033457600080fd5b806336568abe1161017c5780636e2f16961161014b5780636e2f1696146102c857806375b238fc146102db5780637b0472f0146102f0578063817b1cd21461030357600080fd5b806336568abe1461028f5780633f4ba83a146102a25780635c975abb146102aa5780636099ecb2146102b557600080fd5b80630962ef79116101b85780630962ef7914610233578063248a9ca3146102465780632e17de78146102695780632f2ff15d1461027c57600080fd5b8063012ce501146101df57806301ffc9a7146101f45780630359fea91461021c575b600080fd5b6101f26101ed3660046116f9565b6104d0565b005b610207610202366004611712565b61060d565b60405190151581526020015b60405180910390f35b61022560075481565b604051908152602001610213565b6101f26102413660046116f9565b610644565b6102256102543660046116f9565b60009081526020819052604090206001015490565b6101f26102773660046116f9565b610874565b6101f261028a36600461175f565b610af6565b6101f261029d36600461175f565b610b21565b6101f2610b59565b60025460ff16610207565b6102256102c336600461178b565b610b79565b6102256102d63660046117b5565b610c58565b6102256000805160206119ab83398151915281565b6101f26102fe3660046117d0565b610d79565b61022560055481565b61031f61031a3660046117b5565b610fbc565b60405161021391906117f2565b6101f261106c565b6101f26103423660046116f9565b61108c565b61020761035536600461175f565b611173565b610225600081565b6103897f000000000000000000000000b523a5381200650b41ac47868b25f03e8b95b94081565b6040516001600160a01b039091168152602001610213565b6103b46103af36600461178b565b61119c565b6040805196875260208701959095529385019290925260608401526080830152151560a082015260c001610213565b6101f26103f136600461186c565b6111f3565b6102256104043660046117b5565b6001600160a01b031660009081526003602052604090205490565b61045761042d3660046116f9565b60046020526000908152604090208054600182015460028301546003909301549192909160ff1684565b6040805194855260208501939093529183015215156060820152608001610213565b6101f261048736600461175f565b6112f2565b61022561271081565b6102256301e1338081565b61022560065481565b6102257f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b92981565b6104d8611317565b33600090815260036020526040902054811061050f5760405162461bcd60e51b8152600401610506906118b2565b60405180910390fd5b336000908152600360205260408120805483908110610530576105306118dc565b60009182526020909120600690910201600581015490915060ff166105675760405162461bcd60e51b8152600401610506906118f2565b80546005808301805460ff191690558054829190600090610589908490611932565b909155506105c390506001600160a01b037f000000000000000000000000b523a5381200650b41ac47868b25f03e8b95b940163383611341565b604080518481526020810183905233917fbb757047c2b5f3974fe26b7c10f732e7bce710b0952a71082702781e62ae059591015b60405180910390a2505061060a60018055565b50565b60006001600160e01b03198216637965db0b60e01b148061063e57506301ffc9a760e01b6001600160e01b03198316145b92915050565b61064c611317565b33600090815260036020526040902054811061067a5760405162461bcd60e51b8152600401610506906118b2565b33600090815260036020526040812080548390811061069b5761069b6118dc565b60009182526020909120600690910201600581015490915060ff166106d25760405162461bcd60e51b8152600401610506906118f2565b6040805160c08101825282548152600183015460208201526002830154918101919091526003820154606082015260048201546080820152600582015460ff16151560a0820152600090610725906113a0565b90506000811161076e5760405162461bcd60e51b81526020600482015260146024820152734e6f207265776172647320617661696c61626c6560601b6044820152606401610506565b8060075410156107bc5760405162461bcd60e51b8152602060048201526019602482015278125b9cdd59999a58da595b9d081c995dd85c991cc81c1bdbdb603a1b6044820152606401610506565b808260040160008282546107d09190611945565b9250508190555080600760008282546107e99190611932565b9250508190555080600660008282546108029190611945565b9091555061083c90506001600160a01b037f000000000000000000000000b523a5381200650b41ac47868b25f03e8b95b940163383611341565b604080518481526020810183905233917fdacbdde355ba930696a362ea6738feb9f8bd52dfb3d81947558fd3217e23e32591016105f7565b61087c611317565b3360009081526003602052604090205481106108aa5760405162461bcd60e51b8152600401610506906118b2565b3360009081526003602052604081208054839081106108cb576108cb6118dc565b60009182526020909120600690910201600581015490915060ff166109025760405162461bcd60e51b8152600401610506906118f2565b806002015481600101546109169190611945565b42101561095d5760405162461bcd60e51b8152602060048201526015602482015274131bd8dac81c195c9a5bd9081b9bdd08195b991959605a1b6044820152606401610506565b6040805160c08101825282548152600183015460208201526002830154918101919091526003820154606082015260048201546080820152600582015460ff16151560a08201526000906109b0906113a0565b905060008183600001546109c49190611945565b6005808501805460ff1916905584548154929350916000906109e7908490611932565b90915550508115610a7157816007541015610a405760405162461bcd60e51b8152602060048201526019602482015278125b9cdd59999a58da595b9d081c995dd85c991cc81c1bdbdb603a1b6044820152606401610506565b8160076000828254610a529190611932565b925050819055508160066000828254610a6b9190611945565b90915550505b610aa56001600160a01b037f000000000000000000000000b523a5381200650b41ac47868b25f03e8b95b940163383611341565b8254604080518681526020810192909252810183905233907f204fccf0d92ed8d48f204adb39b2e81e92bad0dedb93f5716ca9478cfb57de009060600160405180910390a250505061060a60018055565b600082815260208190526040902060010154610b1181611437565b610b1b8383611441565b50505050565b6001600160a01b0381163314610b4a5760405163334bd91960e11b815260040160405180910390fd5b610b5482826114d3565b505050565b6000805160206119ab833981519152610b7181611437565b61060a61153e565b6001600160a01b0382166000908152600360205260408120548210610bb05760405162461bcd60e51b8152600401610506906118b2565b6001600160a01b0383166000908152600360205260408120805484908110610bda57610bda6118dc565b60009182526020918290206040805160c081018252600690930290910180548352600181015493830193909352600283015490820152600382015460608201526004820154608082015260059091015460ff16151560a08201819052909150610c4757600091505061063e565b610c50816113a0565b949350505050565b6001600160a01b0381166000908152600360209081526040808320805482518185028101850190935280835284938493929190849084015b82821015610cfd5760008481526020908190206040805160c08101825260068602909201805483526001808201548486015260028201549284019290925260038101546060840152600481015460808401526005015460ff16151560a08301529083529092019101610c90565b50505050905060005b8151811015610d7057818181518110610d2157610d216118dc565b602002602001015160a0015115610d5e57818181518110610d4457610d446118dc565b60200260200101516000015183610d5b9190611945565b92505b80610d6881611958565b915050610d06565b50909392505050565b610d81611317565b610d89611590565b60008211610dd35760405162461bcd60e51b8152602060048201526017602482015276416d6f756e74206d75737420626520706f73697469766560481b6044820152606401610506565b60008181526004602090815260409182902082516080810184528154815260018201549281019290925260028101549282019290925260039091015460ff16151560608201819052610e675760405162461bcd60e51b815260206004820152601860248201527f496e76616c6964206f7220696e616374697665207469657200000000000000006044820152606401610506565b610e9c6001600160a01b037f000000000000000000000000b523a5381200650b41ac47868b25f03e8b95b940163330866115b6565b336000908152600360208181526040808420815160c08101835288815242818501908152928101888152878501516060830190815260808301888152600160a0850181815286548083018855968b52978a20945160069096029094019485559451928401929092555160028301555193810193909355516004830155516005918201805460ff19169115159190911790558054859290610f3d908490611945565b909155505033600090815260036020526040812054610f5e90600190611932565b602080840151604080518481529283018890528201869052606082015290915033907f9cfd25589d1eb8ad71e342a86a8524e83522e3936c0803048c08f6d9ad974f409060800160405180910390a25050610fb860018055565b5050565b6001600160a01b0381166000908152600360209081526040808320805482518185028101850190935280835260609492939192909184015b828210156110615760008481526020908190206040805160c08101825260068602909201805483526001808201548486015260028201549284019290925260038101546060840152600481015460808401526005015460ff16151560a08301529083529092019101610ff4565b505050509050919050565b6000805160206119ab83398151915261108481611437565b61060a6115ef565b6000805160206119ab8339815191526110a481611437565b600082116110ee5760405162461bcd60e51b8152602060048201526017602482015276416d6f756e74206d75737420626520706f73697469766560481b6044820152606401610506565b6111236001600160a01b037f000000000000000000000000b523a5381200650b41ac47868b25f03e8b95b940163330856115b6565b81600760008282546111359190611945565b909155505060405182815233907fb8b27d0db504fa5d914f1fd330347096e88d5ff94b6c612d32797e7c12a8f66f9060200160405180910390a25050565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b600360205281600052604060002081815481106111b857600080fd5b600091825260209091206006909102018054600182015460028301546003840154600485015460059095015493965091945092909160ff1686565b6000805160206119ab83398151915261120b81611437565b61271084111561124c5760405162461bcd60e51b815260206004820152600c60248201526b082a0a440e8dede40d0d2ced60a31b6044820152606401610506565b60408051608080820183528782526020808301888152838501888152871515606080870182815260008e81526004875289902097518855935160018801559151600287015591516003909501805460ff19169515159590951790945584518a8152918201899052938101879052918201929092527f05d4036401e9924f65639a62f654cc632427f9aa354735867985d233ed2b02e7910160405180910390a15050505050565b60008281526020819052604090206001015461130d81611437565b610b1b83836114d3565b60026001540361133a57604051633ee5aeb560e01b815260040160405180910390fd5b6002600155565b6040516001600160a01b03838116602483015260448201839052610b5491859182169063a9059cbb906064015b604051602081830303815290604052915060e01b6020820180516001600160e01b03838183161783525050505061162c565b60008160a001516113b357506000919050565b60008260200151426113c59190611932565b9050806000036113d85750600092915050565b60006113ea6301e13380612710611971565b6060850151855184916113fc91611971565b6114069190611971565b6114109190611988565b9050836080015181111561142d576080840151610c509082611932565b5060009392505050565b61060a813361169d565b600061144d8383611173565b6114cb576000838152602081815260408083206001600160a01b03861684529091529020805460ff191660011790556114833390565b6001600160a01b0316826001600160a01b0316847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a450600161063e565b50600061063e565b60006114df8383611173565b156114cb576000838152602081815260408083206001600160a01b0386168085529252808320805460ff1916905551339286917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a450600161063e565b6115466116d6565b6002805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b60025460ff16156115b45760405163d93c066560e01b815260040160405180910390fd5b565b6040516001600160a01b038481166024830152838116604483015260648201839052610b1b9186918216906323b872dd9060840161136e565b6115f7611590565b6002805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586115733390565b600080602060008451602086016000885af18061164f576040513d6000823e3d81fd5b50506000513d91508115611667578060011415611674565b6001600160a01b0384163b155b15610b1b57604051635274afe760e01b81526001600160a01b0385166004820152602401610506565b6116a78282611173565b610fb85760405163e2517d3f60e01b81526001600160a01b038216600482015260248101839052604401610506565b60025460ff166115b457604051638dfc202b60e01b815260040160405180910390fd5b60006020828403121561170b57600080fd5b5035919050565b60006020828403121561172457600080fd5b81356001600160e01b03198116811461173c57600080fd5b9392505050565b80356001600160a01b038116811461175a57600080fd5b919050565b6000806040838503121561177257600080fd5b8235915061178260208401611743565b90509250929050565b6000806040838503121561179e57600080fd5b6117a783611743565b946020939093013593505050565b6000602082840312156117c757600080fd5b61173c82611743565b600080604083850312156117e357600080fd5b50508035926020909101359150565b602080825282518282018190526000919060409081850190868401855b8281101561185f5781518051855286810151878601528581015186860152606080820151908601526080808201519086015260a09081015115159085015260c0909301929085019060010161180f565b5091979650505050505050565b6000806000806080858703121561188257600080fd5b843593506020850135925060408501359150606085013580151581146118a757600080fd5b939692955090935050565b60208082526010908201526f125b9d985b1a59081cdd185ad948125160821b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b60208082526010908201526f5374616b65206e6f742061637469766560801b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b8181038181111561063e5761063e61191c565b8082018082111561063e5761063e61191c565b60006001820161196a5761196a61191c565b5060010190565b808202811582820484141761063e5761063e61191c565b6000826119a557634e487b7160e01b600052601260045260246000fd5b50049056fea49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c21775a26469706673582212209be5c8ccb49442a980cd4d2ec491b531513dc0639b4e483e2dd3685aa737c74264736f6c63430008140033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000b523a5381200650b41ac47868b25f03e8b95b9400000000000000000000000005ec862ddcedf71ba0022ed14cb58efaba55bdd9a
-----Decoded View---------------
Arg [0] : _ambxToken (address): 0xb523a5381200650b41ac47868b25f03e8b95B940
Arg [1] : admin (address): 0x5Ec862dDCeDF71bA0022ed14cB58EFaBa55BdD9A
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000b523a5381200650b41ac47868b25f03e8b95b940
Arg [1] : 0000000000000000000000005ec862ddcedf71ba0022ed14cb58efaba55bdd9a
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
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.