Source Code
Latest 25 from a total of 132 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Withdraw | 18108133 | 901 days ago | IN | 0 ETH | 0.00119512 | ||||
| Withdraw | 17641522 | 966 days ago | IN | 0 ETH | 0.00148872 | ||||
| Withdraw | 17236057 | 1023 days ago | IN | 0 ETH | 0.00703563 | ||||
| Withdraw | 16657887 | 1104 days ago | IN | 0 ETH | 0.00157962 | ||||
| Withdraw | 15343042 | 1292 days ago | IN | 0 ETH | 0.00170362 | ||||
| Withdraw | 14731473 | 1392 days ago | IN | 0 ETH | 0.00228231 | ||||
| Stake | 14729431 | 1392 days ago | IN | 0 ETH | 0.00310081 | ||||
| Redeem | 14041415 | 1499 days ago | IN | 0 ETH | 0.0091179 | ||||
| Redeem | 14037130 | 1500 days ago | IN | 0 ETH | 0.01257876 | ||||
| Redeem | 14028607 | 1501 days ago | IN | 0 ETH | 0.00790817 | ||||
| Add Hero | 14028591 | 1501 days ago | IN | 0 ETH | 0.0038641 | ||||
| Withdraw | 13764785 | 1542 days ago | IN | 0 ETH | 0.00348006 | ||||
| Redeem | 13727730 | 1548 days ago | IN | 0 ETH | 0.0090989 | ||||
| Redeem | 13626294 | 1564 days ago | IN | 0 ETH | 0.01600417 | ||||
| Redeem | 13488276 | 1586 days ago | IN | 0 ETH | 0.01295107 | ||||
| Withdraw | 13486849 | 1586 days ago | IN | 0 ETH | 0.00981239 | ||||
| Stake | 13478960 | 1587 days ago | IN | 0 ETH | 0.00441397 | ||||
| Add Heroes | 13472042 | 1588 days ago | IN | 0 ETH | 0.00398667 | ||||
| Stake | 13469938 | 1588 days ago | IN | 0 ETH | 0.00995126 | ||||
| Stake | 13463367 | 1589 days ago | IN | 0 ETH | 0.00770107 | ||||
| Withdraw | 13463222 | 1589 days ago | IN | 0 ETH | 0.00639624 | ||||
| Stake | 13352629 | 1607 days ago | IN | 0 ETH | 0.00429022 | ||||
| Withdraw | 13352354 | 1607 days ago | IN | 0 ETH | 0.00341475 | ||||
| Redeem | 13131964 | 1641 days ago | IN | 0 ETH | 0.00553558 | ||||
| Stake | 13119083 | 1643 days ago | IN | 0 ETH | 0.00539811 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
LpPool
Compiler Version
v0.6.12+commit.27d51765
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.8;
import '@openzeppelin/contracts/GSN/Context.sol';
import '@openzeppelin/contracts/access/AccessControl.sol';
import './StakableTokenWrapper.sol';
import '../ERC1155/CryptoKombatCollection.sol';
contract LpPool is Context, StakableTokenWrapper, AccessControl {
CryptoKombatCollection public collection;
uint256 public maxStake;
mapping(address => uint256) public lastUpdateTime;
mapping(address => uint256) public points;
mapping(uint256 => uint256) public heroes;
event MaxStakeChanged(uint256 maxStake);
event HeroAdded(uint256 hero, uint256 price);
event HeroesAdded(uint256[] heroes, uint256[] prices);
event Staked(address indexed user, uint256 amount);
event Withdrawn(address indexed user, uint256 amount);
event Redeemed(address indexed user, uint256 amount);
modifier updateReward(address account) {
if (account != address(0)) {
points[account] = earned(account);
lastUpdateTime[account] = block.timestamp;
}
_;
}
constructor(
CryptoKombatCollection _collectionAddress,
IERC20 _tokenAddress,
uint256 _maxStake
) public StakableTokenWrapper(_tokenAddress) {
collection = _collectionAddress;
_setMaxStake(_maxStake);
_setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
}
function addHero(uint256 heroId, uint256 price) public virtual {
require(hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), 'LpPool: Must have admin role to add hero');
require(price >= 1e18, 'LpPool: Price too low');
heroes[heroId] = price;
emit HeroAdded(heroId, price);
}
function addHeroes(uint256[] memory _heroes, uint256[] memory _prices) public virtual {
require(hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), 'LpPool: Must have admin role to add heroes');
require(_heroes.length == _prices.length, 'LpPool: Heroes and prices length mismatch');
for (uint256 i = 0; i < _heroes.length; i++) {
uint256 heroId = _heroes[i];
uint256 price = _prices[i];
require(price >= 1e18, 'LpPool: Price too low');
heroes[heroId] = price;
}
emit HeroesAdded(_heroes, _prices);
}
function setMaxStake(uint256 _maxStake) public virtual {
require(hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), 'LpPool: Must have admin role to set max stake');
require(_maxStake > 0, 'LpPool: Cannot set zero max stake');
_setMaxStake(_maxStake);
}
function _setMaxStake(uint256 _maxStake) internal {
maxStake = _maxStake;
emit MaxStakeChanged(_maxStake);
}
function earned(address account) public view returns (uint256) {
uint256 blockTime = block.timestamp;
return
points[account].add(blockTime.sub(lastUpdateTime[account]).mul(balanceOf(account).mul(14290)).div(86400));
}
function stake(uint256 amount) public override updateReward(_msgSender()) {
require(amount > 0, 'LpPool: Cannot stake zero amount');
require(amount.add(balanceOf(_msgSender())) <= maxStake, 'LpPool: Cannot stake more than max stake');
super.stake(amount);
emit Staked(_msgSender(), amount);
}
function withdraw(uint256 amount) public override updateReward(_msgSender()) {
require(amount > 0, 'LpPool: Cannot withdraw zero amount');
super.withdraw(amount);
emit Withdrawn(_msgSender(), amount);
}
function exit() external {
withdraw(balanceOf(_msgSender()));
}
function redeem(uint256 hero) public updateReward(_msgSender()) {
require(heroes[hero] != 0, 'LpPool: Hero not found');
require(points[_msgSender()] >= heroes[hero], 'LpPool: Not enough Vombats to redeem for hero');
require(collection.totalSupply(hero) < collection.maxSupply(hero), 'LpPool: Max heroes minted');
points[_msgSender()] = points[_msgSender()].sub(heroes[hero]);
collection.mint(_msgSender(), hero, 1, '');
emit Redeemed(_msgSender(), heroes[hero]);
}
}// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; import "../utils/Context.sol";
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "../utils/EnumerableSet.sol";
import "../utils/Address.sol";
import "../utils/Context.sol";
/**
* @dev Contract module that allows children to implement role-based access
* control mechanisms.
*
* 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:
*
* ```
* 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}:
*
* ```
* 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.
*/
abstract contract AccessControl is Context {
using EnumerableSet for EnumerableSet.AddressSet;
using Address for address;
struct RoleData {
EnumerableSet.AddressSet members;
bytes32 adminRole;
}
mapping (bytes32 => RoleData) private _roles;
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
/**
* @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 signaling this.
*
* _Available since v3.1._
*/
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, an admin role
* bearer except when using {_setupRole}.
*/
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) public view returns (bool) {
return _roles[role].members.contains(account);
}
/**
* @dev Returns the number of accounts that have `role`. Can be used
* together with {getRoleMember} to enumerate all bearers of a role.
*/
function getRoleMemberCount(bytes32 role) public view returns (uint256) {
return _roles[role].members.length();
}
/**
* @dev Returns one of the accounts that have `role`. `index` must be a
* value between 0 and {getRoleMemberCount}, non-inclusive.
*
* Role bearers are not sorted in any particular way, and their ordering may
* change at any point.
*
* WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
* you perform all queries on the same block. See the following
* https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
* for more information.
*/
function getRoleMember(bytes32 role, uint256 index) public view returns (address) {
return _roles[role].members.at(index);
}
/**
* @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 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.
*/
function grantRole(bytes32 role, address account) public virtual {
require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to grant");
_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.
*/
function revokeRole(bytes32 role, address account) public virtual {
require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to revoke");
_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 granted `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `account`.
*/
function renounceRole(bytes32 role, address account) public virtual {
require(account == _msgSender(), "AccessControl: can only renounce roles for self");
_revokeRole(role, account);
}
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event. Note that unlike {grantRole}, this function doesn't perform any
* checks on the calling account.
*
* [WARNING]
* ====
* This function should only be called from the constructor when setting
* up the initial roles for the system.
*
* Using this function in any other way is effectively circumventing the admin
* system imposed by {AccessControl}.
* ====
*/
function _setupRole(bytes32 role, address account) internal virtual {
_grantRole(role, account);
}
/**
* @dev Sets `adminRole` as ``role``'s admin role.
*
* Emits a {RoleAdminChanged} event.
*/
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
emit RoleAdminChanged(role, _roles[role].adminRole, adminRole);
_roles[role].adminRole = adminRole;
}
function _grantRole(bytes32 role, address account) private {
if (_roles[role].members.add(account)) {
emit RoleGranted(role, account, _msgSender());
}
}
function _revokeRole(bytes32 role, address account) private {
if (_roles[role].members.remove(account)) {
emit RoleRevoked(role, account, _msgSender());
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.6.8;
import '@openzeppelin/contracts/GSN/Context.sol';
import '@openzeppelin/contracts/math/SafeMath.sol';
import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
contract StakableTokenWrapper is Context {
using SafeMath for uint256;
IERC20 public token;
constructor(IERC20 _tokenAddress) public {
token = IERC20(_tokenAddress);
}
uint256 private _totalSupply;
mapping(address => uint256) private _balances;
function totalSupply() public view returns (uint256) {
return _totalSupply;
}
function balanceOf(address account) public view returns (uint256) {
return _balances[account];
}
function stake(uint256 amount) public virtual {
_totalSupply = _totalSupply.add(amount);
_balances[_msgSender()] = _balances[_msgSender()].add(amount);
token.transferFrom(_msgSender(), address(this), amount);
}
function withdraw(uint256 amount) public virtual {
_totalSupply = _totalSupply.sub(amount);
_balances[_msgSender()] = _balances[_msgSender()].sub(amount);
token.transfer(_msgSender(), amount);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.6.8;
import './ERC1155Tradable.sol';
contract CryptoKombatCollection is ERC1155Tradable {
constructor(string memory _baseUri, address _proxyRegistryAddress)
public
ERC1155Tradable('Crypto Kombat Collection', 'CKC', _proxyRegistryAddress)
{
_setBaseMetadataURI(_baseUri);
}
function contractURI() public pure returns (string memory) {
return 'https://api.cryptokombat.com/contract/cryptokombat-erc1155';
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
/*
* @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 GSN 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 payable) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes memory) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
/**
* @dev Library for managing
* https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
* types.
*
* Sets have the following properties:
*
* - Elements are added, removed, and checked for existence in constant time
* (O(1)).
* - Elements are enumerated in O(n). No guarantees are made on the ordering.
*
* ```
* contract Example {
* // Add the library methods
* using EnumerableSet for EnumerableSet.AddressSet;
*
* // Declare a set state variable
* EnumerableSet.AddressSet private mySet;
* }
* ```
*
* As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
* and `uint256` (`UintSet`) are supported.
*/
library EnumerableSet {
// To implement this library for multiple types with as little code
// repetition as possible, we write it in terms of a generic Set type with
// bytes32 values.
// The Set implementation uses private functions, and user-facing
// implementations (such as AddressSet) are just wrappers around the
// underlying Set.
// This means that we can only create new EnumerableSets for types that fit
// in bytes32.
struct Set {
// Storage of set values
bytes32[] _values;
// Position of the value in the `values` array, plus 1 because index 0
// means a value is not in the set.
mapping (bytes32 => uint256) _indexes;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function _add(Set storage set, bytes32 value) private returns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
// The value is stored at length-1, but we add 1 to all indexes
// and use 0 as a sentinel value
set._indexes[value] = set._values.length;
return true;
} else {
return false;
}
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function _remove(Set storage set, bytes32 value) private returns (bool) {
// We read and store the value's index to prevent multiple reads from the same storage slot
uint256 valueIndex = set._indexes[value];
if (valueIndex != 0) { // Equivalent to contains(set, value)
// To delete an element from the _values array in O(1), we swap the element to delete with the last one in
// the array, and then remove the last element (sometimes called as 'swap and pop').
// This modifies the order of the array, as noted in {at}.
uint256 toDeleteIndex = valueIndex - 1;
uint256 lastIndex = set._values.length - 1;
// When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs
// so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.
bytes32 lastvalue = set._values[lastIndex];
// Move the last value to the index where the value to delete is
set._values[toDeleteIndex] = lastvalue;
// Update the index for the moved value
set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based
// Delete the slot where the moved value was stored
set._values.pop();
// Delete the index for the deleted slot
delete set._indexes[value];
return true;
} else {
return false;
}
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function _contains(Set storage set, bytes32 value) private view returns (bool) {
return set._indexes[value] != 0;
}
/**
* @dev Returns the number of values on the set. O(1).
*/
function _length(Set storage set) private view returns (uint256) {
return set._values.length;
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function _at(Set storage set, uint256 index) private view returns (bytes32) {
require(set._values.length > index, "EnumerableSet: index out of bounds");
return set._values[index];
}
// Bytes32Set
struct Bytes32Set {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _add(set._inner, value);
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _remove(set._inner, value);
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
return _contains(set._inner, value);
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(Bytes32Set storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
return _at(set._inner, index);
}
// AddressSet
struct AddressSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(AddressSet storage set, address value) internal returns (bool) {
return _add(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(AddressSet storage set, address value) internal returns (bool) {
return _remove(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(AddressSet storage set, address value) internal view returns (bool) {
return _contains(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(AddressSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(AddressSet storage set, uint256 index) internal view returns (address) {
return address(uint160(uint256(_at(set._inner, index))));
}
// UintSet
struct UintSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(UintSet storage set, uint256 value) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(UintSet storage set, uint256 value) internal returns (bool) {
return _remove(set._inner, bytes32(value));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(UintSet storage set, uint256 value) internal view returns (bool) {
return _contains(set._inner, bytes32(value));
}
/**
* @dev Returns the number of values on the set. O(1).
*/
function length(UintSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(UintSet storage set, uint256 index) internal view returns (uint256) {
return uint256(_at(set._inner, index));
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize, which returns 0 for contracts in
// construction, since the code is only stored at the end of the
// constructor execution.
uint256 size;
// solhint-disable-next-line no-inline-assembly
assembly { size := extcodesize(account) }
return size > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
// solhint-disable-next-line avoid-low-level-calls, avoid-call-value
(bool success, ) = recipient.call{ value: amount }("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain`call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.call{ value: value }(data);
return _verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.staticcall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.delegatecall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
// solhint-disable-next-line no-inline-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
/**
* @dev Returns the substraction of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b > a) return (false, 0);
return (true, a - b);
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
/**
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b == 0) return (false, 0);
return (true, a / b);
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b == 0) return (false, 0);
return (true, a % b);
}
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a, "SafeMath: subtraction overflow");
return a - b;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) return 0;
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0, "SafeMath: division by zero");
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0, "SafeMath: modulo by zero");
return a % b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {trySub}.
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
return a - b;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting with custom message on
* division by zero. The result is rounded towards zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryDiv}.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting with custom message when dividing by zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryMod}.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
return a % b;
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount) 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 `amount` 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 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
/**
* @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);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.6.8;
import '@openzeppelin/contracts/access/AccessControl.sol';
import '@openzeppelin/contracts/GSN/Context.sol';
import '@openzeppelin/contracts/access/Ownable.sol';
import './ERC1155.sol';
import '../utils/Strings.sol';
contract OwnableDelegateProxy {}
contract ProxyRegistry {
mapping(address => OwnableDelegateProxy) public proxies;
}
/**
* @title ERC1155Tradable
* ERC1155Tradable - ERC1155 contract that whitelists an operator address,
* has create and mint functionality, and supports useful standards from OpenZeppelin,
like _exists(), name(), symbol(), and totalSupply()
*/
contract ERC1155Tradable is Context, AccessControl, Ownable, ERC1155 {
bytes32 public constant MINTER_ROLE = keccak256('MINTER_ROLE');
using Strings for string;
string internal baseMetadataURI;
address proxyRegistryAddress;
uint256 private _currentTokenID = 0;
mapping(uint256 => address) public creators;
mapping(uint256 => uint256) public tokenSupply;
mapping(uint256 => uint256) public tokenMaxSupply;
// Contract name
string public name;
// Contract symbol
string public symbol;
constructor(
string memory _name,
string memory _symbol,
address _proxyRegistryAddress
) public ERC1155('') {
_setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
_setupRole(MINTER_ROLE, _msgSender());
name = _name;
symbol = _symbol;
proxyRegistryAddress = _proxyRegistryAddress;
}
modifier onlyAdminOrOwner() {
require(
hasRole(DEFAULT_ADMIN_ROLE, _msgSender()) || (owner() == _msgSender()),
'ERC1155Tradable: must have admin or owner role'
);
_;
}
modifier onlyMinter() {
require(hasRole(MINTER_ROLE, _msgSender()), 'ERC1155Tradable: must have minter role');
_;
}
function uri(uint256 _id) public view override returns (string memory) {
require(_exists(_id), 'ERC1155Tradable: token must exists');
return Strings.strConcat(baseMetadataURI, Strings.uint2str(_id));
}
/**
* @dev Returns the total quantity for a token ID
* @param _id uint256 ID of the token to query
* @return amount of token in existence
*/
function totalSupply(uint256 _id) public view returns (uint256) {
return tokenSupply[_id];
}
/**
* @dev Returns the max quantity for a token ID
* @param _id uint256 ID of the token to query
* @return amount of token in existence
*/
function maxSupply(uint256 _id) public view returns (uint256) {
return tokenMaxSupply[_id];
}
/**
* @dev Will update the base URL of token's URI
* @param _newBaseMetadataURI New base URL of token's URI
*/
function setBaseMetadataURI(string memory _newBaseMetadataURI) public onlyAdminOrOwner {
_setBaseMetadataURI(_newBaseMetadataURI);
}
/**
* @dev Creates a new token type and assigns _initial to a sender
* @param _max max supply allowed
* @param _initial Optional amount to supply the first owner
* @param _data Optional data to pass if receiver is contract
* @return tokenId The newly created token ID
*/
function create(
uint256 _max,
uint256 _initial,
bytes memory _data
) external onlyAdminOrOwner returns (uint256 tokenId) {
//TODO Need to test lte condition
require(_initial <= _max, 'ERC1155Tradable: Initial supply cannot be more than max supply');
uint256 id = _getNextTokenID();
_incrementTokenTypeId();
creators[id] = _msgSender();
if (_initial != 0) {
_mint(_msgSender(), id, _initial, _data);
}
tokenSupply[id] = _initial;
tokenMaxSupply[id] = _max;
return id;
}
/**
* @dev Creates some amount of tokens type and assigns initials to a sender
* @param _maxs max supply allowed
* @param _initials Optional amount to supply the first owner
*/
function createBatch(
uint256[] memory _maxs,
uint256[] memory _initials,
bytes memory _data
) external onlyAdminOrOwner {
require(_maxs.length == _initials.length, 'ERC1155Tradable: maxs and initials length mismatch');
uint256[] memory ids = new uint256[](_maxs.length);
uint256[] memory quantities = new uint256[](_maxs.length);
for (uint256 i = 0; i < _maxs.length; i++) {
uint256 max = _maxs[i];
uint256 initial = _initials[i];
//TODO Need to test lte condition
require(initial <= max, 'ERC1155Tradable: Initial supply cannot be more than max supply');
uint256 tokenId = _getNextTokenID();
_incrementTokenTypeId();
creators[tokenId] = _msgSender();
tokenSupply[tokenId] = initial;
tokenMaxSupply[tokenId] = max;
ids[i] = tokenId;
quantities[i] = initial;
}
_mintBatch(_msgSender(), ids, quantities, _data);
}
/**
* @dev Mints some amount of tokens to an address
* @param _to Address of the future owner of the token
* @param _id Token ID to mint
* @param _quantity Amount of tokens to mint
* @param _data Data to pass if receiver is contract
*/
function mint(
address _to,
uint256 _id,
uint256 _quantity,
bytes memory _data
) public onlyMinter {
//TODO Need to test lte condition
require(tokenSupply[_id].add(_quantity) <= tokenMaxSupply[_id], 'ERC1155Tradable: Max supply reached');
tokenSupply[_id] = tokenSupply[_id].add(_quantity);
_mint(_to, _id, _quantity, _data);
}
/**
* @dev Mint tokens for each id in _ids
* @param _to The address to mint tokens to
* @param _ids Array of ids to mint
* @param _quantities Array of amounts of tokens to mint per id
* @param _data Data to pass if receiver is contract
*/
function mintBatch(
address _to,
uint256[] memory _ids,
uint256[] memory _quantities,
bytes memory _data
) public onlyMinter {
require(_to != address(0), 'ERC1155Tradable: mint to the zero address');
require(_ids.length == _quantities.length, 'ERC1155Tradable: ids and amounts length mismatch');
for (uint256 i = 0; i < _ids.length; i++) {
uint256 id = _ids[i];
uint256 quantity = _quantities[i];
//TODO Need to test lte condition
require(tokenSupply[id].add(quantity) <= tokenMaxSupply[id], 'ERC1155Tradable: Max supply reached');
tokenSupply[id] = tokenSupply[id].add(quantity);
}
_mintBatch(_to, _ids, _quantities, _data);
}
/**
* Override isApprovedForAll to whitelist user's OpenSea proxy accounts to enable gas-free listings.
*/
function isApprovedForAll(address _owner, address _operator) public view override returns (bool isOperator) {
// Whitelist OpenSea proxy contract for easy trading.
ProxyRegistry proxyRegistry = ProxyRegistry(proxyRegistryAddress);
if (address(proxyRegistry.proxies(_owner)) == _operator) {
return true;
}
return ERC1155.isApprovedForAll(_owner, _operator);
}
/**
* @dev Returns whether the specified token exists by checking to see if it has a creator
* @param _id uint256 ID of the token to query the existence of
* @return bool whether the token exists
*/
function _exists(uint256 _id) internal view returns (bool) {
return creators[_id] != address(0);
}
/**
* @dev calculates the next token ID based on value of _currentTokenID
* @return uint256 for the next token ID
*/
function _getNextTokenID() private view returns (uint256) {
return _currentTokenID.add(1);
}
/**
* @dev increments the value of _currentTokenID
*/
function _incrementTokenTypeId() private {
_currentTokenID++;
}
/**
* @notice Will update the base URL of token's URI
* @param _newBaseMetadataURI New base URL of token's URI
*/
function _setBaseMetadataURI(string memory _newBaseMetadataURI) internal {
baseMetadataURI = _newBaseMetadataURI;
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor () internal {
address msgSender = _msgSender();
_owner = msgSender;
emit OwnershipTransferred(address(0), msgSender);
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.6.8;
import '@openzeppelin/contracts/token/ERC1155/IERC1155.sol';
import '@openzeppelin/contracts/token/ERC1155/IERC1155MetadataURI.sol';
import '@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol';
import '@openzeppelin/contracts/GSN/Context.sol';
import '@openzeppelin/contracts/introspection/ERC165.sol';
import '@openzeppelin/contracts/math/SafeMath.sol';
import '@openzeppelin/contracts/utils/Address.sol';
/**
*
* @dev Implementation of the basic standard multi-token.
* See https://eips.ethereum.org/EIPS/eip-1155
* Originally based on code by Enjin: https://github.com/enjin/erc-1155
*
* _Available since v3.1._
*/
contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
using SafeMath for uint256;
using Address for address;
// Mapping from token ID to account balances
mapping(uint256 => mapping(address => uint256)) private _balances;
// Mapping from account to operator approvals
mapping(address => mapping(address => bool)) private _operatorApprovals;
// Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json
string private _uri;
/*
* bytes4(keccak256('balanceOf(address,uint256)')) == 0x00fdd58e
* bytes4(keccak256('balanceOfBatch(address[],uint256[])')) == 0x4e1273f4
* bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465
* bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5
* bytes4(keccak256('safeTransferFrom(address,address,uint256,uint256,bytes)')) == 0xf242432a
* bytes4(keccak256('safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)')) == 0x2eb2c2d6
*
* => 0x00fdd58e ^ 0x4e1273f4 ^ 0xa22cb465 ^
* 0xe985e9c5 ^ 0xf242432a ^ 0x2eb2c2d6 == 0xd9b67a26
*/
bytes4 private constant _INTERFACE_ID_ERC1155 = 0xd9b67a26;
/*
* bytes4(keccak256('uri(uint256)')) == 0x0e89341c
*/
bytes4 private constant _INTERFACE_ID_ERC1155_METADATA_URI = 0x0e89341c;
/**
* @dev See {_setURI}.
*/
constructor(string memory uri) public {
_setURI(uri);
// register the supported interfaces to conform to ERC1155 via ERC165
_registerInterface(_INTERFACE_ID_ERC1155);
// register the supported interfaces to conform to ERC1155MetadataURI via ERC165
_registerInterface(_INTERFACE_ID_ERC1155_METADATA_URI);
}
/**
* @dev See {IERC1155MetadataURI-uri}.
*
* This implementation returns the same URI for *all* token types. It relies
* on the token type ID substitution mechanism
* https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
*
* Clients calling this function must replace the `\{id\}` substring with the
* actual token type ID.
*/
function uri(uint256) external view virtual override returns (string memory) {
return _uri;
}
/**
* @dev See {IERC1155-balanceOf}.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/
function balanceOf(address account, uint256 id) public view override returns (uint256) {
require(account != address(0), 'ERC1155: balance query for the zero address');
return _balances[id][account];
}
/**
* @dev See {IERC1155-balanceOfBatch}.
*
* Requirements:
*
* - `accounts` and `ids` must have the same length.
*/
function balanceOfBatch(address[] memory accounts, uint256[] memory ids)
public
view
override
returns (uint256[] memory)
{
require(accounts.length == ids.length, 'ERC1155: accounts and ids length mismatch');
uint256[] memory batchBalances = new uint256[](accounts.length);
for (uint256 i = 0; i < accounts.length; ++i) {
require(accounts[i] != address(0), 'ERC1155: batch balance query for the zero address');
batchBalances[i] = _balances[ids[i]][accounts[i]];
}
return batchBalances;
}
/**
* @dev See {IERC1155-setApprovalForAll}.
*/
function setApprovalForAll(address operator, bool approved) public virtual override {
require(_msgSender() != operator, 'ERC1155: setting approval status for self');
_operatorApprovals[_msgSender()][operator] = approved;
emit ApprovalForAll(_msgSender(), operator, approved);
}
/**
* @dev See {IERC1155-isApprovedForAll}.
*/
function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {
return _operatorApprovals[account][operator];
}
/**
* @dev See {IERC1155-safeTransferFrom}.
*/
function safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
) public virtual override {
require(to != address(0), 'ERC1155: transfer to the zero address');
require(
from == _msgSender() || isApprovedForAll(from, _msgSender()),
'ERC1155: caller is not owner nor approved'
);
address operator = _msgSender();
_beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data);
_balances[id][from] = _balances[id][from].sub(amount, 'ERC1155: insufficient balance for transfer');
_balances[id][to] = _balances[id][to].add(amount);
emit TransferSingle(operator, from, to, id, amount);
_doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);
}
/**
* @dev See {IERC1155-safeBatchTransferFrom}.
*/
function safeBatchTransferFrom(
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) public virtual override {
require(ids.length == amounts.length, 'ERC1155: ids and amounts length mismatch');
require(to != address(0), 'ERC1155: transfer to the zero address');
require(
from == _msgSender() || isApprovedForAll(from, _msgSender()),
'ERC1155: transfer caller is not owner nor approved'
);
address operator = _msgSender();
_beforeTokenTransfer(operator, from, to, ids, amounts, data);
for (uint256 i = 0; i < ids.length; ++i) {
uint256 id = ids[i];
uint256 amount = amounts[i];
_balances[id][from] = _balances[id][from].sub(amount, 'ERC1155: insufficient balance for transfer');
_balances[id][to] = _balances[id][to].add(amount);
}
emit TransferBatch(operator, from, to, ids, amounts);
_doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);
}
/**
* @dev Sets a new URI for all token types, by relying on the token type ID
* substitution mechanism
* https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
*
* By this mechanism, any occurrence of the `\{id\}` substring in either the
* URI or any of the amounts in the JSON file at said URI will be replaced by
* clients with the token type ID.
*
* For example, the `https://token-cdn-domain/\{id\}.json` URI would be
* interpreted by clients as
* `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`
* for token type ID 0x4cce0.
*
* See {uri}.
*
* Because these URIs cannot be meaningfully represented by the {URI} event,
* this function emits no events.
*/
function _setURI(string memory newuri) internal virtual {
_uri = newuri;
}
/**
* @dev Creates `amount` tokens of token type `id`, and assigns them to `account`.
*
* Emits a {TransferSingle} event.
*
* Requirements:
*
* - `account` cannot be the zero address.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
* acceptance magic value.
*/
function _mint(
address account,
uint256 id,
uint256 amount,
bytes memory data
) internal virtual {
require(account != address(0), 'ERC1155: mint to the zero address');
address operator = _msgSender();
_beforeTokenTransfer(operator, address(0), account, _asSingletonArray(id), _asSingletonArray(amount), data);
_balances[id][account] = _balances[id][account].add(amount);
emit TransferSingle(operator, address(0), account, id, amount);
_doSafeTransferAcceptanceCheck(operator, address(0), account, id, amount, data);
}
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.
*
* Requirements:
*
* - `ids` and `amounts` must have the same length.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
* acceptance magic value.
*/
function _mintBatch(
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual {
require(to != address(0), 'ERC1155: mint to the zero address');
require(ids.length == amounts.length, 'ERC1155: ids and amounts length mismatch');
address operator = _msgSender();
_beforeTokenTransfer(operator, address(0), to, ids, amounts, data);
for (uint256 i = 0; i < ids.length; i++) {
_balances[ids[i]][to] = amounts[i].add(_balances[ids[i]][to]);
}
emit TransferBatch(operator, address(0), to, ids, amounts);
_doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);
}
/**
* @dev Destroys `amount` tokens of token type `id` from `account`
*
* Requirements:
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens of token type `id`.
*/
function _burn(
address account,
uint256 id,
uint256 amount
) internal virtual {
require(account != address(0), 'ERC1155: burn from the zero address');
address operator = _msgSender();
_beforeTokenTransfer(operator, account, address(0), _asSingletonArray(id), _asSingletonArray(amount), '');
_balances[id][account] = _balances[id][account].sub(amount, 'ERC1155: burn amount exceeds balance');
emit TransferSingle(operator, account, address(0), id, amount);
}
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.
*
* Requirements:
*
* - `ids` and `amounts` must have the same length.
*/
function _burnBatch(
address account,
uint256[] memory ids,
uint256[] memory amounts
) internal virtual {
require(account != address(0), 'ERC1155: burn from the zero address');
require(ids.length == amounts.length, 'ERC1155: ids and amounts length mismatch');
address operator = _msgSender();
_beforeTokenTransfer(operator, account, address(0), ids, amounts, '');
for (uint256 i = 0; i < ids.length; i++) {
_balances[ids[i]][account] = _balances[ids[i]][account].sub(
amounts[i],
'ERC1155: burn amount exceeds balance'
);
}
emit TransferBatch(operator, account, address(0), ids, amounts);
}
/**
* @dev Hook that is called before any token transfer. This includes minting
* and burning, as well as batched variants.
*
* The same hook is called on both single and batched variants. For single
* transfers, the length of the `id` and `amount` arrays will be 1.
*
* Calling conditions (for each `id` and `amount` pair):
*
* - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* of token type `id` will be transferred to `to`.
* - When `from` is zero, `amount` tokens of token type `id` will be minted
* for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens of token type `id`
* will be burned.
* - `from` and `to` are never both zero.
* - `ids` and `amounts` have the same, non-zero length.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual {}
function _doSafeTransferAcceptanceCheck(
address operator,
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
) private {
if (to.isContract()) {
try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {
if (response != IERC1155Receiver(to).onERC1155Received.selector) {
revert('ERC1155: ERC1155Receiver rejected tokens');
}
} catch Error(string memory reason) {
revert(reason);
} catch {
revert('ERC1155: transfer to non ERC1155Receiver implementer');
}
}
}
function _doSafeBatchTransferAcceptanceCheck(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) private {
if (to.isContract()) {
try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (
bytes4 response
) {
if (response != IERC1155Receiver(to).onERC1155BatchReceived.selector) {
revert('ERC1155: ERC1155Receiver rejected tokens');
}
} catch Error(string memory reason) {
revert(reason);
} catch {
revert('ERC1155: transfer to non ERC1155Receiver implementer');
}
}
}
function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {
uint256[] memory array = new uint256[](1);
array[0] = element;
return array;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.6.8;
library Strings {
// via https://github.com/oraclize/ethereum-api/blob/master/oraclizeAPI_0.5.sol
function strConcat(
string memory _a,
string memory _b,
string memory _c,
string memory _d,
string memory _e
) internal pure returns (string memory) {
bytes memory _ba = bytes(_a);
bytes memory _bb = bytes(_b);
bytes memory _bc = bytes(_c);
bytes memory _bd = bytes(_d);
bytes memory _be = bytes(_e);
string memory abcde = new string(
_ba.length + _bb.length + _bc.length + _bd.length + _be.length
);
bytes memory babcde = bytes(abcde);
uint256 k = 0;
for (uint256 i = 0; i < _ba.length; i++) babcde[k++] = _ba[i];
for (uint256 i = 0; i < _bb.length; i++) babcde[k++] = _bb[i];
for (uint256 i = 0; i < _bc.length; i++) babcde[k++] = _bc[i];
for (uint256 i = 0; i < _bd.length; i++) babcde[k++] = _bd[i];
for (uint256 i = 0; i < _be.length; i++) babcde[k++] = _be[i];
return string(babcde);
}
function strConcat(
string memory _a,
string memory _b,
string memory _c,
string memory _d
) internal pure returns (string memory) {
return strConcat(_a, _b, _c, _d, "");
}
function strConcat(
string memory _a,
string memory _b,
string memory _c
) internal pure returns (string memory) {
return strConcat(_a, _b, _c, "", "");
}
function strConcat(string memory _a, string memory _b)
internal
pure
returns (string memory)
{
return strConcat(_a, _b, "", "", "");
}
function uint2str(uint256 _i)
internal
pure
returns (string memory _uintAsString)
{
if (_i == 0) {
return "0";
}
uint256 j = _i;
uint256 len;
while (j != 0) {
len++;
j /= 10;
}
bytes memory bstr = new bytes(len);
uint256 k = len - 1;
while (_i != 0) {
bstr[k--] = bytes1(uint8(48 + (_i % 10)));
_i /= 10;
}
return string(bstr);
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0;
import "../../introspection/IERC165.sol";
/**
* @dev Required interface of an ERC1155 compliant contract, as defined in the
* https://eips.ethereum.org/EIPS/eip-1155[EIP].
*
* _Available since v3.1._
*/
interface IERC1155 is IERC165 {
/**
* @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.
*/
event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);
/**
* @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all
* transfers.
*/
event TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);
/**
* @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to
* `approved`.
*/
event ApprovalForAll(address indexed account, address indexed operator, bool approved);
/**
* @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.
*
* If an {URI} event was emitted for `id`, the standard
* https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value
* returned by {IERC1155MetadataURI-uri}.
*/
event URI(string value, uint256 indexed id);
/**
* @dev Returns the amount of tokens of token type `id` owned by `account`.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/
function balanceOf(address account, uint256 id) external view returns (uint256);
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.
*
* Requirements:
*
* - `accounts` and `ids` must have the same length.
*/
function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory);
/**
* @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,
*
* Emits an {ApprovalForAll} event.
*
* Requirements:
*
* - `operator` cannot be the caller.
*/
function setApprovalForAll(address operator, bool approved) external;
/**
* @dev Returns true if `operator` is approved to transfer ``account``'s tokens.
*
* See {setApprovalForAll}.
*/
function isApprovedForAll(address account, address operator) external view returns (bool);
/**
* @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
*
* Emits a {TransferSingle} event.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}.
* - `from` must have a balance of tokens of type `id` of at least `amount`.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
* acceptance magic value.
*/
function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.
*
* Emits a {TransferBatch} event.
*
* Requirements:
*
* - `ids` and `amounts` must have the same length.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
* acceptance magic value.
*/
function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0;
import "./IERC1155.sol";
/**
* @dev Interface of the optional ERC1155MetadataExtension interface, as defined
* in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].
*
* _Available since v3.1._
*/
interface IERC1155MetadataURI is IERC1155 {
/**
* @dev Returns the URI for token type `id`.
*
* If the `\{id\}` substring is present in the URI, it must be replaced by
* clients with the actual token type ID.
*/
function uri(uint256 id) external view returns (string memory);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "../../introspection/IERC165.sol";
/**
* _Available since v3.1._
*/
interface IERC1155Receiver is IERC165 {
/**
@dev Handles the receipt of a single ERC1155 token type. This function is
called at the end of a `safeTransferFrom` after the balance has been updated.
To accept the transfer, this must return
`bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
(i.e. 0xf23a6e61, or its own function selector).
@param operator The address which initiated the transfer (i.e. msg.sender)
@param from The address which previously owned the token
@param id The ID of the token being transferred
@param value The amount of tokens being transferred
@param data Additional data with no specified format
@return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed
*/
function onERC1155Received(
address operator,
address from,
uint256 id,
uint256 value,
bytes calldata data
)
external
returns(bytes4);
/**
@dev Handles the receipt of a multiple ERC1155 token types. This function
is called at the end of a `safeBatchTransferFrom` after the balances have
been updated. To accept the transfer(s), this must return
`bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
(i.e. 0xbc197c81, or its own function selector).
@param operator The address which initiated the batch transfer (i.e. msg.sender)
@param from The address which previously owned the token
@param ids An array containing ids of each token being transferred (order and length must match values array)
@param values An array containing amounts of each token being transferred (order and length must match ids array)
@param data Additional data with no specified format
@return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed
*/
function onERC1155BatchReceived(
address operator,
address from,
uint256[] calldata ids,
uint256[] calldata values,
bytes calldata data
)
external
returns(bytes4);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts may inherit from this and call {_registerInterface} to declare
* their support of an interface.
*/
abstract contract ERC165 is IERC165 {
/*
* bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7
*/
bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;
/**
* @dev Mapping of interface ids to whether or not it's supported.
*/
mapping(bytes4 => bool) private _supportedInterfaces;
constructor () internal {
// Derived contracts need only register support for their own interfaces,
// we register support for ERC165 itself here
_registerInterface(_INTERFACE_ID_ERC165);
}
/**
* @dev See {IERC165-supportsInterface}.
*
* Time complexity O(1), guaranteed to always use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return _supportedInterfaces[interfaceId];
}
/**
* @dev Registers the contract as an implementer of the interface defined by
* `interfaceId`. Support of the actual ERC165 interface is automatic and
* registering its interface id is not required.
*
* See {IERC165-supportsInterface}.
*
* Requirements:
*
* - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).
*/
function _registerInterface(bytes4 interfaceId) internal virtual {
require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
_supportedInterfaces[interfaceId] = true;
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* 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[EIP 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);
}{
"optimizer": {
"enabled": true,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"abi"
]
}
},
"metadata": {
"useLiteralContent": true
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"contract CryptoKombatCollection","name":"_collectionAddress","type":"address"},{"internalType":"contract IERC20","name":"_tokenAddress","type":"address"},{"internalType":"uint256","name":"_maxStake","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"hero","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"}],"name":"HeroAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256[]","name":"heroes","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"prices","type":"uint256[]"}],"name":"HeroesAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"maxStake","type":"uint256"}],"name":"MaxStakeChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Redeemed","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":"amount","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":"Withdrawn","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"heroId","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"}],"name":"addHero","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_heroes","type":"uint256[]"},{"internalType":"uint256[]","name":"_prices","type":"uint256[]"}],"name":"addHeroes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"collection","outputs":[{"internalType":"contract CryptoKombatCollection","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"earned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"exit","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":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","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":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"heroes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lastUpdateTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxStake","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"points","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"hero","type":"uint256"}],"name":"redeem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","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":[{"internalType":"uint256","name":"_maxStake","type":"uint256"}],"name":"setMaxStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60806040523480156200001157600080fd5b5060405162001b8938038062001b89833981810160405260608110156200003757600080fd5b5080516020820151604090920151600080546001600160a01b038086166001600160a01b03199283161790925560048054928516929091169190911790559091906200008381620000a2565b62000099600062000093620000dd565b620000e1565b505050620001f3565b60058190556040805182815290517fe7b292db9682cb68712e9ea62977bc7b3eac6086443b853be43f91a24273a1af9181900360200190a150565b3390565b620000ed8282620000f1565b5050565b600082815260036020908152604090912062000118918390620011286200016c821b17901c565b15620000ed5762000128620000dd565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600062000183836001600160a01b0384166200018c565b90505b92915050565b60006200019a8383620001db565b620001d25750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000186565b50600062000186565b60009081526001919091016020526040902054151590565b61198680620002036000396000f3fe608060405234801561001057600080fd5b50600436106101575760003560e01c80637de1e536116100c3578063ca15c8731161007c578063ca15c873146104d2578063d547741f146104ef578063db006a751461051b578063e9fad8ee14610538578063ea1b28e014610540578063fc0c546a1461054857610157565b80637de1e536146104095780639010d07c1461042d57806391d1485414610450578063a217fddf14610490578063a694fc3a14610498578063a8d4a03b146104b557610157565b80632f2ff15d116101155780632f2ff15d14610325578063358b81661461035157806336568abe1461037757806359a7968e146103a35780636fc14837146103c657806370a08231146103e357610157565b80628cc2621461015c57806318160ddd146101945780631e709dea1461019c578063248a9ca3146102c55780632ce9aead146102e25780632e1a7d4d14610308575b600080fd5b6101826004803603602081101561017257600080fd5b50356001600160a01b0316610550565b60408051918252519081900360200190f35b6101826105c5565b6102c3600480360360408110156101b257600080fd5b8101906020810181356401000000008111156101cd57600080fd5b8201836020820111156101df57600080fd5b8035906020019184602083028401116401000000008311171561020157600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929594936020810193503591505064010000000081111561025157600080fd5b82018360208201111561026357600080fd5b8035906020019184602083028401116401000000008311171561028557600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295506105cb945050505050565b005b610182600480360360208110156102db57600080fd5b50356107c1565b610182600480360360208110156102f857600080fd5b50356001600160a01b03166107d6565b6102c36004803603602081101561031e57600080fd5b50356107e8565b6102c36004803603604081101561033b57600080fd5b50803590602001356001600160a01b03166108c4565b6101826004803603602081101561036757600080fd5b50356001600160a01b031661092b565b6102c36004803603604081101561038d57600080fd5b50803590602001356001600160a01b031661093d565b6102c3600480360360408110156103b957600080fd5b508035906020013561099e565b6102c3600480360360208110156103dc57600080fd5b5035610a8c565b610182600480360360208110156103f957600080fd5b50356001600160a01b0316610b1f565b610411610b3a565b604080516001600160a01b039092168252519081900360200190f35b6104116004803603604081101561044357600080fd5b5080359060200135610b49565b61047c6004803603604081101561046657600080fd5b50803590602001356001600160a01b0316610b6a565b604080519115158252519081900360200190f35b610182610b82565b6102c3600480360360208110156104ae57600080fd5b5035610b87565b610182600480360360208110156104cb57600080fd5b5035610cd3565b610182600480360360208110156104e857600080fd5b5035610ce5565b6102c36004803603604081101561050557600080fd5b50803590602001356001600160a01b0316610cfc565b6102c36004803603602081101561053157600080fd5b5035610d55565b6102c36110fe565b610182611113565b610411611119565b6000426105be61059f620151806105996105756137d261056f89610b1f565b9061113d565b6001600160a01b03881660009081526006602052604090205461056f908790611196565b906111f3565b6001600160a01b0385166000908152600760205260409020549061125a565b9392505050565b60015490565b6105dd60006105d86112b4565b610b6a565b6106185760405162461bcd60e51b815260040180806020018281038252602a81526020018061185f602a913960400191505060405180910390fd5b80518251146106585760405162461bcd60e51b815260040180806020018281038252602981526020018061173f6029913960400191505060405180910390fd5b60005b825181101561070157600083828151811061067257fe5b60200260200101519050600083838151811061068a57fe5b60200260200101519050670de0b6b3a76400008110156106e9576040805162461bcd60e51b81526020600482015260156024820152744c70506f6f6c3a20507269636520746f6f206c6f7760581b604482015290519081900360640190fd5b6000918252600860205260409091205560010161065b565b507f2978ca6ff8f0be9cb0bd4ef9a257dc9795d02c57bd36f0630cba36d51d7be5a98282604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b83811015610769578181015183820152602001610751565b50505050905001838103825284818151815260200191508051906020019060200280838360005b838110156107a8578181015183820152602001610790565b5050505090500194505050505060405180910390a15050565b60009081526003602052604090206002015490565b60066020526000908152604090205481565b6107f06112b4565b6001600160a01b038116156108305761080881610550565b6001600160a01b03821660009081526007602090815260408083209390935560069052204290555b6000821161086f5760405162461bcd60e51b81526004018080602001828103825260238152602001806118ff6023913960400191505060405180910390fd5b610878826112b8565b6108806112b4565b6001600160a01b03167f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d5836040518082815260200191505060405180910390a25050565b6000828152600360205260409020600201546108e2906105d86112b4565b61091d5760405162461bcd60e51b815260040180806020018281038252602f81526020018061178a602f913960400191505060405180910390fd5b610927828261138b565b5050565b60076020526000908152604090205481565b6109456112b4565b6001600160a01b0316816001600160a01b0316146109945760405162461bcd60e51b815260040180806020018281038252602f815260200180611922602f913960400191505060405180910390fd5b61092782826113f4565b6109ab60006105d86112b4565b6109e65760405162461bcd60e51b81526004018080602001828103825260288152602001806118166028913960400191505060405180910390fd5b670de0b6b3a7640000811015610a3b576040805162461bcd60e51b81526020600482015260156024820152744c70506f6f6c3a20507269636520746f6f206c6f7760581b604482015290519081900360640190fd5b600082815260086020908152604091829020839055815184815290810183905281517f4aeeb492b165811c0e00a6afa6cec0ed3fdcb802c522ea1610c8ea02c6a85a8c929181900390910190a15050565b610a9960006105d86112b4565b610ad45760405162461bcd60e51b815260040180806020018281038252602d8152602001806117e9602d913960400191505060405180910390fd5b60008111610b135760405162461bcd60e51b81526004018080602001828103825260218152602001806118de6021913960400191505060405180910390fd5b610b1c8161145d565b50565b6001600160a01b031660009081526002602052604090205490565b6004546001600160a01b031681565b6000828152600360205260408120610b619083611498565b90505b92915050565b6000828152600360205260408120610b6190836114a4565b600081565b610b8f6112b4565b6001600160a01b03811615610bcf57610ba781610550565b6001600160a01b03821660009081526007602090815260408083209390935560069052204290555b60008211610c24576040805162461bcd60e51b815260206004820181905260248201527f4c70506f6f6c3a2043616e6e6f74207374616b65207a65726f20616d6f756e74604482015290519081900360640190fd5b600554610c41610c3a610c356112b4565b610b1f565b849061125a565b1115610c7e5760405162461bcd60e51b81526004018080602001828103825260288152602001806118b66028913960400191505060405180910390fd5b610c87826114b9565b610c8f6112b4565b6001600160a01b03167f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d836040518082815260200191505060405180910390a25050565b60086020526000908152604090205481565b6000818152600360205260408120610b649061158e565b600082815260036020526040902060020154610d1a906105d86112b4565b6109945760405162461bcd60e51b81526004018080602001828103825260308152602001806117b96030913960400191505060405180910390fd5b610d5d6112b4565b6001600160a01b03811615610d9d57610d7581610550565b6001600160a01b03821660009081526007602090815260408083209390935560069052204290555b600082815260086020526040902054610df6576040805162461bcd60e51b8152602060048201526016602482015275131c141bdbdb0e8812195c9bc81b9bdd08199bdd5b9960521b604482015290519081900360640190fd5b60008281526008602052604081205490600790610e116112b4565b6001600160a01b03166001600160a01b03168152602001908152602001600020541015610e6f5760405162461bcd60e51b815260040180806020018281038252602d815260200180611889602d913960400191505060405180910390fd5b60048054604080516321a7dd6560e21b8152928301859052516001600160a01b039091169163869f7594916024808301926020929190829003018186803b158015610eb957600080fd5b505afa158015610ecd573d6000803e3d6000fd5b505050506040513d6020811015610ee357600080fd5b5051600480546040805163bd85b03960e01b8152928301869052516001600160a01b039091169163bd85b039916024808301926020929190829003018186803b158015610f2f57600080fd5b505afa158015610f43573d6000803e3d6000fd5b505050506040513d6020811015610f5957600080fd5b505110610fad576040805162461bcd60e51b815260206004820152601960248201527f4c70506f6f6c3a204d6178206865726f6573206d696e74656400000000000000604482015290519081900360640190fd5b600082815260086020526040812054610feb91600790610fcb6112b4565b6001600160a01b0316815260208101919091526040016000205490611196565b60076000610ff76112b4565b6001600160a01b0390811682526020820192909252604001600020919091556004541663731133e96110276112b4565b604080516001600160e01b031960e085901b1681526001600160a01b039092166004830152602482018690526001604483015260806064830152600060848301819052905160c48084019382900301818387803b15801561108757600080fd5b505af115801561109b573d6000803e3d6000fd5b505050506110a76112b4565b6001600160a01b03167f4896181ff8f4543cc00db9fe9b6fb7e6f032b7eb772c72ab1ec1b4d2e03b936960086000858152602001908152602001600020546040518082815260200191505060405180910390a25050565b61111161110c610c356112b4565b6107e8565b565b60055481565b6000546001600160a01b031681565b6000610b61836001600160a01b038416611599565b60008261114c57506000610b64565b8282028284828161115957fe5b0414610b615760405162461bcd60e51b815260040180806020018281038252602181526020018061183e6021913960400191505060405180910390fd5b6000828211156111ed576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b6000808211611249576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b81838161125257fe5b049392505050565b600082820183811015610b61576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b3390565b6001546112c59082611196565b6001556112d88160026000610fcb6112b4565b600260006112e46112b4565b6001600160a01b039081168252602082019290925260400160009081209290925590541663a9059cbb6113156112b4565b836040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b15801561135c57600080fd5b505af1158015611370573d6000803e3d6000fd5b505050506040513d602081101561138657600080fd5b505050565b60008281526003602052604090206113a39082611128565b15610927576113b06112b4565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600082815260036020526040902061140c90826115e3565b15610927576114196112b4565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b60058190556040805182815290517fe7b292db9682cb68712e9ea62977bc7b3eac6086443b853be43f91a24273a1af9181900360200190a150565b6000610b6183836115f8565b6000610b61836001600160a01b03841661165c565b6001546114c6908261125a565b6001556114f981600260006114d96112b4565b6001600160a01b031681526020810191909152604001600020549061125a565b600260006115056112b4565b6001600160a01b03908116825260208201929092526040016000908120929092559054166323b872dd6115366112b4565b30846040518463ffffffff1660e01b815260040180846001600160a01b03168152602001836001600160a01b031681526020018281526020019350505050602060405180830381600087803b15801561135c57600080fd5b6000610b6482611674565b60006115a5838361165c565b6115db57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610b64565b506000610b64565b6000610b61836001600160a01b038416611678565b8154600090821061163a5760405162461bcd60e51b81526004018080602001828103825260228152602001806117686022913960400191505060405180910390fd5b82600001828154811061164957fe5b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b5490565b6000818152600183016020526040812054801561173457835460001980830191908101906000908790839081106116ab57fe5b90600052602060002001549050808760000184815481106116c857fe5b6000918252602080832090910192909255828152600189810190925260409020908401905586548790806116f857fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610b64565b6000915050610b6456fe4c70506f6f6c3a204865726f657320616e6420707269636573206c656e677468206d69736d61746368456e756d657261626c655365743a20696e646578206f7574206f6620626f756e6473416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f206772616e74416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f207265766f6b654c70506f6f6c3a204d75737420686176652061646d696e20726f6c6520746f20736574206d6178207374616b654c70506f6f6c3a204d75737420686176652061646d696e20726f6c6520746f20616464206865726f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774c70506f6f6c3a204d75737420686176652061646d696e20726f6c6520746f20616464206865726f65734c70506f6f6c3a204e6f7420656e6f75676820566f6d6261747320746f2072656465656d20666f72206865726f4c70506f6f6c3a2043616e6e6f74207374616b65206d6f7265207468616e206d6178207374616b654c70506f6f6c3a2043616e6e6f7420736574207a65726f206d6178207374616b654c70506f6f6c3a2043616e6e6f74207769746864726177207a65726f20616d6f756e74416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636520726f6c657320666f722073656c66a2646970667358221220e1e4622843c3fcbe303b57e49caea632d6931329de1f8640b4ab21c225c6314164736f6c634300060c0033000000000000000000000000d0f27dfa54fbf80b823a63470c0e693ae4a626b80000000000000000000000004c3c158fec9adc51390f8986e904bc6ca24b95e00000000000000000000000000000000000000000000000000000befe6f672000
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101575760003560e01c80637de1e536116100c3578063ca15c8731161007c578063ca15c873146104d2578063d547741f146104ef578063db006a751461051b578063e9fad8ee14610538578063ea1b28e014610540578063fc0c546a1461054857610157565b80637de1e536146104095780639010d07c1461042d57806391d1485414610450578063a217fddf14610490578063a694fc3a14610498578063a8d4a03b146104b557610157565b80632f2ff15d116101155780632f2ff15d14610325578063358b81661461035157806336568abe1461037757806359a7968e146103a35780636fc14837146103c657806370a08231146103e357610157565b80628cc2621461015c57806318160ddd146101945780631e709dea1461019c578063248a9ca3146102c55780632ce9aead146102e25780632e1a7d4d14610308575b600080fd5b6101826004803603602081101561017257600080fd5b50356001600160a01b0316610550565b60408051918252519081900360200190f35b6101826105c5565b6102c3600480360360408110156101b257600080fd5b8101906020810181356401000000008111156101cd57600080fd5b8201836020820111156101df57600080fd5b8035906020019184602083028401116401000000008311171561020157600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929594936020810193503591505064010000000081111561025157600080fd5b82018360208201111561026357600080fd5b8035906020019184602083028401116401000000008311171561028557600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295506105cb945050505050565b005b610182600480360360208110156102db57600080fd5b50356107c1565b610182600480360360208110156102f857600080fd5b50356001600160a01b03166107d6565b6102c36004803603602081101561031e57600080fd5b50356107e8565b6102c36004803603604081101561033b57600080fd5b50803590602001356001600160a01b03166108c4565b6101826004803603602081101561036757600080fd5b50356001600160a01b031661092b565b6102c36004803603604081101561038d57600080fd5b50803590602001356001600160a01b031661093d565b6102c3600480360360408110156103b957600080fd5b508035906020013561099e565b6102c3600480360360208110156103dc57600080fd5b5035610a8c565b610182600480360360208110156103f957600080fd5b50356001600160a01b0316610b1f565b610411610b3a565b604080516001600160a01b039092168252519081900360200190f35b6104116004803603604081101561044357600080fd5b5080359060200135610b49565b61047c6004803603604081101561046657600080fd5b50803590602001356001600160a01b0316610b6a565b604080519115158252519081900360200190f35b610182610b82565b6102c3600480360360208110156104ae57600080fd5b5035610b87565b610182600480360360208110156104cb57600080fd5b5035610cd3565b610182600480360360208110156104e857600080fd5b5035610ce5565b6102c36004803603604081101561050557600080fd5b50803590602001356001600160a01b0316610cfc565b6102c36004803603602081101561053157600080fd5b5035610d55565b6102c36110fe565b610182611113565b610411611119565b6000426105be61059f620151806105996105756137d261056f89610b1f565b9061113d565b6001600160a01b03881660009081526006602052604090205461056f908790611196565b906111f3565b6001600160a01b0385166000908152600760205260409020549061125a565b9392505050565b60015490565b6105dd60006105d86112b4565b610b6a565b6106185760405162461bcd60e51b815260040180806020018281038252602a81526020018061185f602a913960400191505060405180910390fd5b80518251146106585760405162461bcd60e51b815260040180806020018281038252602981526020018061173f6029913960400191505060405180910390fd5b60005b825181101561070157600083828151811061067257fe5b60200260200101519050600083838151811061068a57fe5b60200260200101519050670de0b6b3a76400008110156106e9576040805162461bcd60e51b81526020600482015260156024820152744c70506f6f6c3a20507269636520746f6f206c6f7760581b604482015290519081900360640190fd5b6000918252600860205260409091205560010161065b565b507f2978ca6ff8f0be9cb0bd4ef9a257dc9795d02c57bd36f0630cba36d51d7be5a98282604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b83811015610769578181015183820152602001610751565b50505050905001838103825284818151815260200191508051906020019060200280838360005b838110156107a8578181015183820152602001610790565b5050505090500194505050505060405180910390a15050565b60009081526003602052604090206002015490565b60066020526000908152604090205481565b6107f06112b4565b6001600160a01b038116156108305761080881610550565b6001600160a01b03821660009081526007602090815260408083209390935560069052204290555b6000821161086f5760405162461bcd60e51b81526004018080602001828103825260238152602001806118ff6023913960400191505060405180910390fd5b610878826112b8565b6108806112b4565b6001600160a01b03167f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d5836040518082815260200191505060405180910390a25050565b6000828152600360205260409020600201546108e2906105d86112b4565b61091d5760405162461bcd60e51b815260040180806020018281038252602f81526020018061178a602f913960400191505060405180910390fd5b610927828261138b565b5050565b60076020526000908152604090205481565b6109456112b4565b6001600160a01b0316816001600160a01b0316146109945760405162461bcd60e51b815260040180806020018281038252602f815260200180611922602f913960400191505060405180910390fd5b61092782826113f4565b6109ab60006105d86112b4565b6109e65760405162461bcd60e51b81526004018080602001828103825260288152602001806118166028913960400191505060405180910390fd5b670de0b6b3a7640000811015610a3b576040805162461bcd60e51b81526020600482015260156024820152744c70506f6f6c3a20507269636520746f6f206c6f7760581b604482015290519081900360640190fd5b600082815260086020908152604091829020839055815184815290810183905281517f4aeeb492b165811c0e00a6afa6cec0ed3fdcb802c522ea1610c8ea02c6a85a8c929181900390910190a15050565b610a9960006105d86112b4565b610ad45760405162461bcd60e51b815260040180806020018281038252602d8152602001806117e9602d913960400191505060405180910390fd5b60008111610b135760405162461bcd60e51b81526004018080602001828103825260218152602001806118de6021913960400191505060405180910390fd5b610b1c8161145d565b50565b6001600160a01b031660009081526002602052604090205490565b6004546001600160a01b031681565b6000828152600360205260408120610b619083611498565b90505b92915050565b6000828152600360205260408120610b6190836114a4565b600081565b610b8f6112b4565b6001600160a01b03811615610bcf57610ba781610550565b6001600160a01b03821660009081526007602090815260408083209390935560069052204290555b60008211610c24576040805162461bcd60e51b815260206004820181905260248201527f4c70506f6f6c3a2043616e6e6f74207374616b65207a65726f20616d6f756e74604482015290519081900360640190fd5b600554610c41610c3a610c356112b4565b610b1f565b849061125a565b1115610c7e5760405162461bcd60e51b81526004018080602001828103825260288152602001806118b66028913960400191505060405180910390fd5b610c87826114b9565b610c8f6112b4565b6001600160a01b03167f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d836040518082815260200191505060405180910390a25050565b60086020526000908152604090205481565b6000818152600360205260408120610b649061158e565b600082815260036020526040902060020154610d1a906105d86112b4565b6109945760405162461bcd60e51b81526004018080602001828103825260308152602001806117b96030913960400191505060405180910390fd5b610d5d6112b4565b6001600160a01b03811615610d9d57610d7581610550565b6001600160a01b03821660009081526007602090815260408083209390935560069052204290555b600082815260086020526040902054610df6576040805162461bcd60e51b8152602060048201526016602482015275131c141bdbdb0e8812195c9bc81b9bdd08199bdd5b9960521b604482015290519081900360640190fd5b60008281526008602052604081205490600790610e116112b4565b6001600160a01b03166001600160a01b03168152602001908152602001600020541015610e6f5760405162461bcd60e51b815260040180806020018281038252602d815260200180611889602d913960400191505060405180910390fd5b60048054604080516321a7dd6560e21b8152928301859052516001600160a01b039091169163869f7594916024808301926020929190829003018186803b158015610eb957600080fd5b505afa158015610ecd573d6000803e3d6000fd5b505050506040513d6020811015610ee357600080fd5b5051600480546040805163bd85b03960e01b8152928301869052516001600160a01b039091169163bd85b039916024808301926020929190829003018186803b158015610f2f57600080fd5b505afa158015610f43573d6000803e3d6000fd5b505050506040513d6020811015610f5957600080fd5b505110610fad576040805162461bcd60e51b815260206004820152601960248201527f4c70506f6f6c3a204d6178206865726f6573206d696e74656400000000000000604482015290519081900360640190fd5b600082815260086020526040812054610feb91600790610fcb6112b4565b6001600160a01b0316815260208101919091526040016000205490611196565b60076000610ff76112b4565b6001600160a01b0390811682526020820192909252604001600020919091556004541663731133e96110276112b4565b604080516001600160e01b031960e085901b1681526001600160a01b039092166004830152602482018690526001604483015260806064830152600060848301819052905160c48084019382900301818387803b15801561108757600080fd5b505af115801561109b573d6000803e3d6000fd5b505050506110a76112b4565b6001600160a01b03167f4896181ff8f4543cc00db9fe9b6fb7e6f032b7eb772c72ab1ec1b4d2e03b936960086000858152602001908152602001600020546040518082815260200191505060405180910390a25050565b61111161110c610c356112b4565b6107e8565b565b60055481565b6000546001600160a01b031681565b6000610b61836001600160a01b038416611599565b60008261114c57506000610b64565b8282028284828161115957fe5b0414610b615760405162461bcd60e51b815260040180806020018281038252602181526020018061183e6021913960400191505060405180910390fd5b6000828211156111ed576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b6000808211611249576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b81838161125257fe5b049392505050565b600082820183811015610b61576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b3390565b6001546112c59082611196565b6001556112d88160026000610fcb6112b4565b600260006112e46112b4565b6001600160a01b039081168252602082019290925260400160009081209290925590541663a9059cbb6113156112b4565b836040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b15801561135c57600080fd5b505af1158015611370573d6000803e3d6000fd5b505050506040513d602081101561138657600080fd5b505050565b60008281526003602052604090206113a39082611128565b15610927576113b06112b4565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600082815260036020526040902061140c90826115e3565b15610927576114196112b4565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b60058190556040805182815290517fe7b292db9682cb68712e9ea62977bc7b3eac6086443b853be43f91a24273a1af9181900360200190a150565b6000610b6183836115f8565b6000610b61836001600160a01b03841661165c565b6001546114c6908261125a565b6001556114f981600260006114d96112b4565b6001600160a01b031681526020810191909152604001600020549061125a565b600260006115056112b4565b6001600160a01b03908116825260208201929092526040016000908120929092559054166323b872dd6115366112b4565b30846040518463ffffffff1660e01b815260040180846001600160a01b03168152602001836001600160a01b031681526020018281526020019350505050602060405180830381600087803b15801561135c57600080fd5b6000610b6482611674565b60006115a5838361165c565b6115db57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610b64565b506000610b64565b6000610b61836001600160a01b038416611678565b8154600090821061163a5760405162461bcd60e51b81526004018080602001828103825260228152602001806117686022913960400191505060405180910390fd5b82600001828154811061164957fe5b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b5490565b6000818152600183016020526040812054801561173457835460001980830191908101906000908790839081106116ab57fe5b90600052602060002001549050808760000184815481106116c857fe5b6000918252602080832090910192909255828152600189810190925260409020908401905586548790806116f857fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610b64565b6000915050610b6456fe4c70506f6f6c3a204865726f657320616e6420707269636573206c656e677468206d69736d61746368456e756d657261626c655365743a20696e646578206f7574206f6620626f756e6473416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f206772616e74416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f207265766f6b654c70506f6f6c3a204d75737420686176652061646d696e20726f6c6520746f20736574206d6178207374616b654c70506f6f6c3a204d75737420686176652061646d696e20726f6c6520746f20616464206865726f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774c70506f6f6c3a204d75737420686176652061646d696e20726f6c6520746f20616464206865726f65734c70506f6f6c3a204e6f7420656e6f75676820566f6d6261747320746f2072656465656d20666f72206865726f4c70506f6f6c3a2043616e6e6f74207374616b65206d6f7265207468616e206d6178207374616b654c70506f6f6c3a2043616e6e6f7420736574207a65726f206d6178207374616b654c70506f6f6c3a2043616e6e6f74207769746864726177207a65726f20616d6f756e74416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636520726f6c657320666f722073656c66a2646970667358221220e1e4622843c3fcbe303b57e49caea632d6931329de1f8640b4ab21c225c6314164736f6c634300060c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000d0f27dfa54fbf80b823a63470c0e693ae4a626b80000000000000000000000004c3c158fec9adc51390f8986e904bc6ca24b95e00000000000000000000000000000000000000000000000000000befe6f672000
-----Decoded View---------------
Arg [0] : _collectionAddress (address): 0xD0f27dfa54FbF80b823a63470C0e693AE4A626b8
Arg [1] : _tokenAddress (address): 0x4C3c158FEc9ADc51390f8986e904Bc6Ca24b95e0
Arg [2] : _maxStake (uint256): 210000000000000
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000d0f27dfa54fbf80b823a63470c0e693ae4a626b8
Arg [1] : 0000000000000000000000004c3c158fec9adc51390f8986e904bc6ca24b95e0
Arg [2] : 0000000000000000000000000000000000000000000000000000befe6f672000
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ 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.