Contract Overview
Balance:
0 CLV
CLV Value:
$0.00
My Name Tag:
Not Available, login to update
Txn Hash | Method |
Block
|
From
|
To
|
Value | [Txn Fee] | |||
---|---|---|---|---|---|---|---|---|---|
0x59c0378934590d4045a41ee24394257a81394a272c2daa43ed974095455f0b19 | 0x60806040 | 2711683 | 12 days 14 hrs ago | 0xd134a7d9485c1aac0cbf82718cf6d6e3fd130945 | IN | Create: ERC1155StakingModuleFactory | 0 CLV | 0.01716805 |
[ Download CSV Export ]
Contract Name:
ERC1155StakingModuleFactory
Compiler Version
v0.8.4+commit.c7e474f2
Optimization Enabled:
Yes with 1000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol) pragma solidity ^0.8.0; import "../../utils/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 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 // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev _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. * * NOTE: 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. * * NOTE: 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 // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/utils/ERC1155Holder.sol) pragma solidity ^0.8.0; import "./ERC1155Receiver.sol"; /** * Simple implementation of `ERC1155Receiver` that will allow a contract to hold ERC1155 tokens. * * IMPORTANT: When inheriting this contract, you must include a way to use the received tokens, otherwise they will be * stuck. * * @dev _Available since v3.1._ */ contract ERC1155Holder is ERC1155Receiver { function onERC1155Received( address, address, uint256, uint256, bytes memory ) public virtual override returns (bytes4) { return this.onERC1155Received.selector; } function onERC1155BatchReceived( address, address, uint256[] memory, uint256[] memory, bytes memory ) public virtual override returns (bytes4) { return this.onERC1155BatchReceived.selector; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC1155/utils/ERC1155Receiver.sol) pragma solidity ^0.8.0; import "../IERC1155Receiver.sol"; import "../../../utils/introspection/ERC165.sol"; /** * @dev _Available since v3.1._ */ abstract contract ERC1155Receiver is ERC165, IERC1155Receiver { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the 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 `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, 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 `from` to `to` 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 from, address to, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^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); }
/* ERC1155StakingModule https://github.com/FanbaseEU/Staking_Ethereum_SmartContracts SPDX-License-Identifier: MIT */ pragma solidity ^0.8.4; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol"; import "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol"; import "./interfaces/IStakingModule.sol"; /** * @title ERC721 staking module * * @notice this staking module allows users to deposit one or more ERC721 * tokens in exchange for shares credited to their address. When the user * unstakes, these shares will be burned and a reward will be distributed. */ contract ERC1155StakingModule is IStakingModule { // constant uint256 public constant SHARES_PER_TOKEN = 10**18; mapping(uint256 => uint256) public sharePerTokenId; // members IERC1155 private immutable _token; address public immutable _factory; mapping(address => uint256) public userTotalBalance; mapping(address => mapping(uint256 => uint256)) public counts; mapping(uint256 => address) public owners; mapping(address => mapping(uint256 => uint256)) public tokenByOwner; mapping(uint256 => uint256) public tokenIndex; // newly defined uint256 private totalBalance; uint256[] public stakedTokenIds; event StakedERC1155(address user, address token, uint256[] tokenIds, uint256[] amounts, uint256 shares); // checksum bytes4 constant internal ERC1155_RECEIVED_VALUE = 0xf23a6e61; bytes4 constant internal ERC1155_BATCH_RECEIVED_VALUE = 0xbc197c81; /** * @param token_ the token that will be rewarded */ constructor(address token_, address factory_) { require( IERC165(token_).supportsInterface(0xd9b67a26), "Interface ID not matched" ); _token = IERC1155(token_); _factory = factory_; } /** * @inheritdoc IStakingModule */ function tokens() external view override returns (address[] memory tokens_) { tokens_ = new address[](1); tokens_[0] = address(_token); } /** * @inheritdoc IStakingModule */ function balances(address user) external view override returns (uint256[] memory balances_) { balances_ = new uint256[](1); balances_[0] = userTotalBalance[user]; } /** * @inheritdoc IStakingModule */ function factory() external view override returns (address) { return _factory; } /** * @inheritdoc IStakingModule */ function totals() external view override returns (uint256[] memory totals_) { totals_ = new uint256[](1); totals_[0] = totalBalance; } /** * @inheritdoc IStakingModule */ // function stake( // address user, // uint256 amount, // bytes calldata data // ) external override onlyOwner returns (address, uint256) { // // validate // require(amount > 0, "Staking amount must be greater than 0"); // require(amount <= _token.balanceOf(user), "Insufficient balance"); // require(data.length == 32 * amount, "Invalid calldata"); // uint256 count = counts[user]; // // stake // for (uint256 i = 0; i < amount; i++) { // // get token id // uint256 id; // uint256 pos = 132 + 32 * i; // assembly { // id := calldataload(pos) // } // // ownership mappings // owners[id] = user; // uint256 len = count + i; // tokenByOwner[user][len] = id; // tokenIndex[id] = len; // // transfer to module // _token.transferFrom(user, address(this), id); // } // // update position // counts[user] = count + amount; // // emit // uint256 shares = amount * SHARES_PER_TOKEN; // emit Staked(user, address(_token), amount, shares); // return (user, shares); // } function stake( address user, uint256 amount, bytes calldata data ) external override onlyOwner returns (address, uint256) { require(data.length == 32, "Invalid calldata"); uint256 tokenId; assembly { tokenId := calldataload(68) } uint256 shares = amount * sharePerTokenId[tokenId]; emit Staked(user, address(_token), amount, shares); return (user, shares); } function _stake( address user, uint256[] memory tokenIds, uint256[] memory amounts ) internal returns (address, uint256) { uint256 shares; for (uint256 i = 0; i < tokenIds.length; i++) { require(amounts[i] > 0, "Staking amount must be greater than 0"); counts[user][tokenIds[i]] = counts[user][tokenIds[i]] + amounts[i]; userTotalBalance[user] = userTotalBalance[user] + amounts[i]; shares = shares + amounts[i] * sharePerTokenId[tokenIds[i]]; totalBalance = totalBalance + amounts[i]; stakedTokenIds.push(tokenIds[i]); } emit StakedERC1155(user, address(_token), tokenIds, amounts, shares); return (user, shares); } /** * @inheritdoc IStakingModule */ // function unstake( // address user, // uint256 amount, // bytes calldata data // ) external override onlyOwner returns (address, uint256) { // // validate // require(amount > 0, "Unstaking amount must be greater than 0"); // uint256 count = counts[user]; // require(amount <= count, "Insufficient staked balance"); // require(data.length == 32 * amount, "Invalid calldata"); // // unstake // for (uint256 i = 0; i < amount; i++) { // // get token id // uint256 id; // uint256 pos = 132 + 32 * i; // assembly { // id := calldataload(pos) // } // // ownership // require(owners[id] == user, "Only owner can unstake"); // delete owners[id]; // // clean up ownership mappings // uint256 lastIndex = count - 1 - i; // if (amount != count) { // // reindex on partial unstake // uint256 index = tokenIndex[id]; // if (index != lastIndex) { // uint256 lastId = tokenByOwner[user][lastIndex]; // tokenByOwner[user][index] = lastId; // tokenIndex[lastId] = index; // } // } // delete tokenByOwner[user][lastIndex]; // delete tokenIndex[id]; // // transfer to user // _token.safeTransferFrom(address(this), user, id); // } // // update position // counts[user] = count - amount; // // emit // uint256 shares = amount * SHARES_PER_TOKEN; // emit Unstaked(user, address(_token), amount, shares); // return (user, shares); // } function unstake( address user, uint256 amount, bytes calldata data ) external override onlyOwner returns (address, uint256) { require(data.length == 32, "Invalid calldata"); uint256 tokenId; assembly { tokenId := calldataload(68) } require(amount > 0, "Unstaking amount must be greater than 0"); require(counts[user][tokenId] >= amount, "Insufficient staked balance"); counts[user][tokenId] = counts[user][tokenId] - amount; userTotalBalance[user] = userTotalBalance[user] - amount; // decrease total balance totalBalance = totalBalance - amount; _token.safeTransferFrom(address(this), user, tokenId, amount, ""); uint256 shares = amount * sharePerTokenId[tokenId]; emit Unstaked(user, address(_token), amount, shares); return (user, shares); } /** * @inheritdoc IStakingModule */ // function claim( // address user, // uint256 amount, // bytes calldata // ) external override onlyOwner returns (address, uint256) { // // validate // require(amount > 0, "Claiming amount must be greater than 0"); // require(amount <= counts[user], "Insufficient balance"); // uint256 shares = amount * SHARES_PER_TOKEN; // emit Claimed(user, address(_token), amount, shares); // return (user, shares); // } function claim( address user, uint256 amount, bytes calldata data ) external override onlyOwner returns (address, uint256) { require(data.length == 32, "Invalid calldata"); require(amount > 0, "Claiming amount must be greater than 0"); uint256 tokenId; assembly { tokenId := calldataload(68) } require(amount <= counts[user][tokenId], "Insufficient balance"); uint256 shares = amount * sharePerTokenId[tokenId]; emit Claimed(user, address(_token), amount, shares); return (user, shares); } function getStakedTokenIds() public view returns (uint256[] memory) { return stakedTokenIds; } /** * @inheritdoc IStakingModule */ function update(address) external override {} /** * @inheritdoc IStakingModule */ function clean() external override {} /** ERC1155 receiver */ function onERC1155Received( address _operator, address _from, uint256 _id, uint256 _amount, bytes memory _data ) public returns(bytes4) { uint256[] memory ids = new uint256[](1); uint256[] memory amounts = new uint256[](1); ids[0] = _id; amounts[0] = _amount; require( ERC1155_BATCH_RECEIVED_VALUE == onERC1155BatchReceived(_operator, _from, ids, amounts, _data), "NE20#28" ); return ERC1155_RECEIVED_VALUE; } function onERC1155BatchReceived( address, // _operator, address _from, uint256[] memory _ids, uint256[] memory _amounts, bytes memory) public returns(bytes4) { _stake(_from, _ids, _amounts); return ERC1155_BATCH_RECEIVED_VALUE; } }
/* ERC721StakingModuleFactory https://github.com/FanbaseEU/Staking_Ethereum_SmartContracts SPDX-License-Identifier: MIT */ pragma solidity ^0.8.4; import "./interfaces/IModuleFactory.sol"; import "./ERC1155StakingModule.sol"; /** * @title ERC721 staking module factory * * @notice this factory contract handles deployment for the * ERC721StakingModule contract * * @dev it is called by the parent PoolFactory and is responsible * for parsing constructor arguments before creating a new contract */ contract ERC1155StakingModuleFactory is IModuleFactory { /** * @inheritdoc IModuleFactory */ function createModule(bytes calldata data) external override returns (address) { // validate require(data.length == 32, "Invalid calldata"); // parse staking token address token; assembly { token := calldataload(68) } // create module ERC1155StakingModule module = new ERC1155StakingModule(token, address(this)); module.transferOwnership(msg.sender); // output emit ModuleCreated(msg.sender, address(module)); return address(module); } }
/* IEvents https://github.com/FanbaseEU/Staking_Ethereum_SmartContracts SPDX-License-Identifier: MIT */ pragma solidity 0.8.4; /** * @title GYSR event system * * @notice common interface to define GYSR event system */ interface IEvents { // staking event Staked( address indexed user, address indexed token, uint256 amount, uint256 shares ); event Unstaked( address indexed user, address indexed token, uint256 amount, uint256 shares ); event Claimed( address indexed user, address indexed token, uint256 amount, uint256 shares ); // rewards event RewardsDistributed( address indexed user, address indexed token, uint256 amount, uint256 shares ); event RewardsFunded( address indexed token, uint256 amount, uint256 shares, uint256 timestamp ); event RewardsUnlocked(address indexed token, uint256 shares); event RewardsExpired( address indexed token, uint256 amount, uint256 shares, uint256 timestamp ); // gysr event GysrSpent(address indexed user, uint256 amount); event GysrVested(address indexed user, uint256 amount); event GysrWithdrawn(uint256 amount); }
/* IModuleFactory https://github.com/FanbaseEU/Staking_Ethereum_SmartContracts SPDX-License-Identifier: MIT */ pragma solidity 0.8.4; /** * @title Module factory interface * * @notice this defines the common module factory interface used by the * main factory to create the staking and reward modules for a new Pool. */ interface IModuleFactory { // events event ModuleCreated(address indexed user, address module); /** * @notice create a new Pool module * @param data binary encoded construction parameters * @return address of newly created module */ function createModule(bytes calldata data) external returns (address); }
/* IStakingModule https://github.com/FanbaseEU/Staking_Ethereum_SmartContracts SPDX-License-Identifier: MIT */ pragma solidity 0.8.4; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "./IEvents.sol"; import "../OwnerController.sol"; /** * @title Staking module interface * * @notice this contract defines the common interface that any staking module * must implement to be compatible with the modular Pool architecture. */ abstract contract IStakingModule is OwnerController, IEvents { // constants uint256 public constant DECIMALS = 18; /** * @return array of staking tokens */ function tokens() external view virtual returns (address[] memory); /** * @notice get balance of user * @param user address of user * @return balances of each staking token */ function balances(address user) external view virtual returns (uint256[] memory); /** * @return address of module factory */ function factory() external view virtual returns (address); /** * @notice get total staked amount * @return totals for each staking token */ function totals() external view virtual returns (uint256[] memory); /** * @notice stake an amount of tokens for user * @param user address of user * @param amount number of tokens to stake * @param data additional data * @return address of staking account * @return number of shares minted for stake */ function stake( address user, uint256 amount, bytes calldata data ) external virtual returns (address, uint256); /** * @notice unstake an amount of tokens for user * @param user address of user * @param amount number of tokens to unstake * @param data additional data * @return address of staking account * @return number of shares burned for unstake */ function unstake( address user, uint256 amount, bytes calldata data ) external virtual returns (address, uint256); /** * @notice quote the share value for an amount of tokens without unstaking * @param user address of user * @param amount number of tokens to claim with * @param data additional data * @return address of staking account * @return number of shares that the claim amount is worth */ function claim( address user, uint256 amount, bytes calldata data ) external virtual returns (address, uint256); /** * @notice method called by anyone to update accounting * @param user address of user for update * @dev will only be called ad hoc and should not contain essential logic */ function update(address user) external virtual; /** * @notice method called by owner to clean up and perform additional accounting * @dev will only be called ad hoc and should not contain any essential logic */ function clean() external virtual; }
/* OwnerController https://github.com/FanbaseEU/Staking_Ethereum_SmartContracts SPDX-License-Identifier: MIT */ pragma solidity 0.8.4; /** * @title Owner controller * * @notice this base contract implements an owner-controller access model. * * @dev the contract is an adapted version of the OpenZeppelin Ownable contract. * It allows the owner to designate an additional account as the controller to * perform restricted operations. * * Other changes include supporting role verification with a require method * in addition to the modifier option, and removing some unneeded functionality. * * Original contract here: * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol */ contract OwnerController { address private _owner; address private _controller; event OwnershipTransferred( address indexed previousOwner, address indexed newOwner ); event ControlTransferred( address indexed previousController, address indexed newController ); constructor() { _owner = msg.sender; _controller = msg.sender; emit OwnershipTransferred(address(0), _owner); emit ControlTransferred(address(0), _owner); } /** * @dev Returns the address of the current owner. */ function owner() public view returns (address) { return _owner; } /** * @dev Returns the address of the current controller. */ function controller() public view returns (address) { return _controller; } /** * @dev Modifier that throws if called by any account other than the owner. */ modifier onlyOwner() { require(_owner == msg.sender, "Only owner can perform this action"); _; } /** * @dev Modifier that throws if called by any account other than the controller. */ modifier onlyController() { require(_controller == msg.sender, "Only controller can perform this action"); _; } /** * @dev Throws if called by any account other than the owner. */ function requireOwner() internal view { require(_owner == msg.sender, "Only owner can perform this action"); } /** * @dev Throws if called by any account other than the controller. */ function requireController() internal view { require(_controller == msg.sender, "Only controller can perform this action"); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). This can * include renouncing ownership by transferring to the zero address. * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual { requireOwner(); require(newOwner != address(0), "New owner address can't be zero"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } /** * @dev Transfers control of the contract to a new account (`newController`). * Can only be called by the owner. */ function transferControl(address newController) public virtual { requireOwner(); require(newController != address(0), "New controller address can't be zero"); emit ControlTransferred(_controller, newController); _controller = newController; } }
{ "optimizer": { "enabled": true, "runs": 1000 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"address","name":"module","type":"address"}],"name":"ModuleCreated","type":"event"},{"inputs":[{"internalType":"bytes","name":"data","type":"bytes"}],"name":"createModule","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50611e39806100206000396000f3fe608060405234801561001057600080fd5b506004361061002a5760003560e01c8062ee8fe51461002f575b600080fd5b61004261003d366004610215565b61006b565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b6000602082146100db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f496e76616c69642063616c6c6461746100000000000000000000000000000000604482015260640160405180910390fd5b60006044359050600081306040516100f290610208565b73ffffffffffffffffffffffffffffffffffffffff928316815291166020820152604001604051809103906000f080158015610132573d6000803e3d6000fd5b506040517ff2fde38b00000000000000000000000000000000000000000000000000000000815233600482015290915073ffffffffffffffffffffffffffffffffffffffff82169063f2fde38b90602401600060405180830381600087803b15801561019d57600080fd5b505af11580156101b1573d6000803e3d6000fd5b505060405173ffffffffffffffffffffffffffffffffffffffff841681523392507ff708942ec477396a151a5285651961dcab8e8a82ea4f5b31a5236f92f6c92710915060200160405180910390a2949350505050565b611b818061028383390190565b60008060208385031215610227578182fd5b823567ffffffffffffffff8082111561023e578384fd5b818501915085601f830112610251578384fd5b81358181111561025f578485fd5b866020828501011115610270578485fd5b6020929092019691955090935050505056fe60c06040523480156200001157600080fd5b5060405162001b8138038062001b818339810160408190526200003491620001c8565b60008054336001600160a01b0319918216811783556001805490921681179091556040519091907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3600080546040516001600160a01b0390911691907fa06677f7b64342b4bcbde423684dbdb5356acfe41ad0285b6ecbe6dc4bf427f2908290a36040516301ffc9a760e01b8152636cdb3d1360e11b60048201526001600160a01b038316906301ffc9a79060240160206040518083038186803b1580156200010057600080fd5b505afa15801562000115573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200013b9190620001ff565b6200018c5760405162461bcd60e51b815260206004820152601860248201527f496e74657266616365204944206e6f74206d6174636865640000000000000000604482015260640160405180910390fd5b6001600160601b0319606092831b8116608052911b1660a05262000228565b80516001600160a01b0381168114620001c357600080fd5b919050565b60008060408385031215620001db578182fd5b620001e683620001ab565b9150620001f660208401620001ab565b90509250929050565b60006020828403121562000211578081fd5b8151801515811462000221578182fd5b9392505050565b60805160601c60a05160601c6119036200027e600039600081816103f901526104220152600081816105bf015281816108de0152818161098f01528181610ceb01528181610d6601526113e101526119036000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80639d63848a116100ee578063c45a015511610097578063f23a6e6111610071578063f23a6e611461044c578063f2fde38b1461045f578063f77c479114610472578063fc4333cd1461023857600080fd5b8063c45a0155146103f7578063c5cc6b6a1461041d578063edf394df1461044457600080fd5b8063bc197c81116100c8578063bc197c8114610398578063c038a38e146103dc578063c4113b88146103e457600080fd5b80639d63848a146103385780639d8818f01461034d578063af7e2c661461036d57600080fd5b80633e12170f1161015b5780638c7a4638116101355780638c7a4638146102f25780638da5cb5b146103015780638f0bc152146103125780638f7398241461032557600080fd5b80633e12170f1461028d5780636d16fa41146102bf578063821a3e67146102d257600080fd5b8063259fd2211161018c578063259fd2211461023a57806327e235e3146102655780632e0f26251461028557600080fd5b8063025e7c27146101b35780630583e9f8146101f95780631c1b877214610227575b600080fd5b6101dc6101c1366004611704565b6005602052600090815260409020546001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b610219610207366004611704565b60076020526000908152604090205481565b6040519081526020016101f0565b61023861023536600461152f565b50565b005b610219610248366004611659565b600660209081526000928352604080842090915290825290205481565b61027861027336600461152f565b610483565b6040516101f091906117f4565b610219601281565b6102a061029b366004611682565b6104ef565b604080516001600160a01b0390931683526020830191909152016101f0565b6102386102cd36600461152f565b61063e565b6102196102e036600461152f565b60036020526000908152604090205481565b610219670de0b6b3a764000081565b6000546001600160a01b03166101dc565b6102a0610320366004611682565b61072a565b610219610333366004611704565b61094a565b61034061096b565b6040516101f091906117a7565b61021961035b366004611704565b60026020526000908152604090205481565b61021961037b366004611659565b600460209081526000928352604080842090915290825290205481565b6103ab6103a6366004611550565b6109f2565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016101f0565b610278610a13565b6102a06103f2366004611682565b610a68565b7f00000000000000000000000000000000000000000000000000000000000000006101dc565b6101dc7f000000000000000000000000000000000000000000000000000000000000000081565b610278610dd2565b6103ab61045a3660046115f6565b610e2a565b61023861046d36600461152f565b610f7f565b6001546001600160a01b03166101dc565b604080516001808252818301909252606091602080830190803683375050506001600160a01b0383166000908152600360205260408120548251929350918391906104de57634e487b7160e01b600052603260045260246000fd5b602002602001018181525050919050565b6000805481906001600160a01b0316331461055c5760405162461bcd60e51b815260206004820152602260248201527f4f6e6c79206f776e65722063616e20706572666f726d2074686973206163746960448201526137b760f11b60648201526084015b60405180910390fd5b6020831461059f5760405162461bcd60e51b815260206004820152601060248201526f496e76616c69642063616c6c6461746160801b6044820152606401610553565b6044356000818152600260205260408120546105bb9088611850565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316886001600160a01b03167f6c86f3fd5118b3aa8bb4f389a617046de0a3d3d477de1a1673d227f802f616dc898460405161062b929190918252602082015260400190565b60405180910390a3969795505050505050565b610646611047565b6001600160a01b0381166106c15760405162461bcd60e51b8152602060048201526024808201527f4e657720636f6e74726f6c6c657220616464726573732063616e27742062652060448201527f7a65726f000000000000000000000000000000000000000000000000000000006064820152608401610553565b6001546040516001600160a01b038084169216907fa06677f7b64342b4bcbde423684dbdb5356acfe41ad0285b6ecbe6dc4bf427f290600090a36001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b6000805481906001600160a01b031633146107925760405162461bcd60e51b815260206004820152602260248201527f4f6e6c79206f776e65722063616e20706572666f726d2074686973206163746960448201526137b760f11b6064820152608401610553565b602083146107d55760405162461bcd60e51b815260206004820152601060248201526f496e76616c69642063616c6c6461746160801b6044820152606401610553565b6000851161084b5760405162461bcd60e51b815260206004820152602660248201527f436c61696d696e6720616d6f756e74206d75737420626520677265617465722060448201527f7468616e203000000000000000000000000000000000000000000000000000006064820152608401610553565b6001600160a01b03861660009081526004602090815260408083206044358085529252909120548611156108c15760405162461bcd60e51b815260206004820152601460248201527f496e73756666696369656e742062616c616e63650000000000000000000000006044820152606401610553565b6000818152600260205260408120546108da9088611850565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316886001600160a01b03167f2f6639d24651730c7bf57c95ddbf96d66d11477e4ec626876f92c22e5f365e68898460405161062b929190918252602082015260400190565b6009818154811061095a57600080fd5b600091825260209091200154905081565b604080516001808252818301909252606091602080830190803683370190505090507f0000000000000000000000000000000000000000000000000000000000000000816000815181106109cf57634e487b7160e01b600052603260045260246000fd5b60200260200101906001600160a01b031690816001600160a01b03168152505090565b60006109ff8585856110ac565b5063bc197c8160e01b979650505050505050565b6040805160018082528183019092526060916020808301908036833701905050905060085481600081518110610a5957634e487b7160e01b600052603260045260246000fd5b60200260200101818152505090565b6000805481906001600160a01b03163314610ad05760405162461bcd60e51b815260206004820152602260248201527f4f6e6c79206f776e65722063616e20706572666f726d2074686973206163746960448201526137b760f11b6064820152608401610553565b60208314610b135760405162461bcd60e51b815260206004820152601060248201526f496e76616c69642063616c6c6461746160801b6044820152606401610553565b60443585610b895760405162461bcd60e51b815260206004820152602760248201527f556e7374616b696e6720616d6f756e74206d757374206265206772656174657260448201527f207468616e2030000000000000000000000000000000000000000000000000006064820152608401610553565b6001600160a01b0387166000908152600460209081526040808320848452909152902054861115610bfc5760405162461bcd60e51b815260206004820152601b60248201527f496e73756666696369656e74207374616b65642062616c616e636500000000006044820152606401610553565b6001600160a01b0387166000908152600460209081526040808320848452909152902054610c2b90879061186f565b6001600160a01b038816600081815260046020908152604080832086845282528083209490945591815260039091522054610c6790879061186f565b6001600160a01b038816600090815260036020526040902055600854610c8e90879061186f565b6008556040517ff242432a0000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b038881166024830152604482018390526064820188905260a06084830152600060a48301527f0000000000000000000000000000000000000000000000000000000000000000169063f242432a9060c401600060405180830381600087803b158015610d2f57600080fd5b505af1158015610d43573d6000803e3d6000fd5b505050600082815260026020526040812054909150610d629088611850565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316886001600160a01b03167f06cc7e90b4f2b554a9614b0caa84f909f3498c820ae47c731f490c28c07f7d3b898460405161062b929190918252602082015260400190565b60606009805480602002602001604051908101604052809291908181526020018280548015610e2057602002820191906000526020600020905b815481526020019060010190808311610e0c575b5050505050905090565b6040805160018082528183019092526000918291906020808301908036833750506040805160018082528183019092529293506000929150602080830190803683370190505090508582600081518110610e9457634e487b7160e01b600052603260045260246000fd5b6020026020010181815250508481600081518110610ec257634e487b7160e01b600052603260045260246000fd5b602002602001018181525050610edb88888484886109f2565b7fffffffff000000000000000000000000000000000000000000000000000000001663bc197c8160e01b14610f525760405162461bcd60e51b815260206004820152600760248201527f4e453230233238000000000000000000000000000000000000000000000000006044820152606401610553565b507ff23a6e6100000000000000000000000000000000000000000000000000000000979650505050505050565b610f87611047565b6001600160a01b038116610fdd5760405162461bcd60e51b815260206004820152601f60248201527f4e6577206f776e657220616464726573732063616e2774206265207a65726f006044820152606401610553565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b565b6000546001600160a01b031633146110455760405162461bcd60e51b815260206004820152602260248201527f4f6e6c79206f776e65722063616e20706572666f726d2074686973206163746960448201526137b760f11b6064820152608401610553565b60008080805b85518110156113bc5760008582815181106110dd57634e487b7160e01b600052603260045260246000fd5b6020026020010151116111585760405162461bcd60e51b815260206004820152602560248201527f5374616b696e6720616d6f756e74206d7573742062652067726561746572207460448201527f68616e20300000000000000000000000000000000000000000000000000000006064820152608401610553565b84818151811061117857634e487b7160e01b600052603260045260246000fd5b602002602001015160046000896001600160a01b03166001600160a01b0316815260200190815260200160002060008884815181106111c757634e487b7160e01b600052603260045260246000fd5b60200260200101518152602001908152602001600020546111e89190611838565b6001600160a01b0388166000908152600460205260408120885190919089908590811061122557634e487b7160e01b600052603260045260246000fd5b602002602001015181526020019081526020016000208190555084818151811061125f57634e487b7160e01b600052603260045260246000fd5b602002602001015160036000896001600160a01b03166001600160a01b03168152602001908152602001600020546112979190611838565b6001600160a01b0388166000908152600360205260408120919091558651600291908890849081106112d957634e487b7160e01b600052603260045260246000fd5b602002602001015181526020019081526020016000205485828151811061131057634e487b7160e01b600052603260045260246000fd5b60200260200101516113229190611850565b61132c9083611838565b915084818151811061134e57634e487b7160e01b600052603260045260246000fd5b60200260200101516008546113639190611838565b600881905550600986828151811061138b57634e487b7160e01b600052603260045260246000fd5b60209081029190910181015182546001810184556000938452919092200155806113b481611886565b9150506110b2565b507fa8d4e65faa707d7d23651270f14c684fc78adea5eb6143954e8ac787939a8ba9867f0000000000000000000000000000000000000000000000000000000000000000878785604051611414959493929190611756565b60405180910390a194959350505050565b80356001600160a01b038116811461143c57600080fd5b919050565b600082601f830112611451578081fd5b8135602067ffffffffffffffff82111561146d5761146d6118b7565b8160051b61147c828201611807565b838152828101908684018388018501891015611496578687fd5b8693505b858410156114b857803583526001939093019291840191840161149a565b50979650505050505050565b600082601f8301126114d4578081fd5b813567ffffffffffffffff8111156114ee576114ee6118b7565b611501601f8201601f1916602001611807565b818152846020838601011115611515578283fd5b816020850160208301379081016020019190915292915050565b600060208284031215611540578081fd5b61154982611425565b9392505050565b600080600080600060a08688031215611567578081fd5b61157086611425565b945061157e60208701611425565b9350604086013567ffffffffffffffff8082111561159a578283fd5b6115a689838a01611441565b945060608801359150808211156115bb578283fd5b6115c789838a01611441565b935060808801359150808211156115dc578283fd5b506115e9888289016114c4565b9150509295509295909350565b600080600080600060a0868803121561160d578081fd5b61161686611425565b945061162460208701611425565b93506040860135925060608601359150608086013567ffffffffffffffff81111561164d578182fd5b6115e9888289016114c4565b6000806040838503121561166b578182fd5b61167483611425565b946020939093013593505050565b60008060008060608587031215611697578384fd5b6116a085611425565b935060208501359250604085013567ffffffffffffffff808211156116c3578384fd5b818701915087601f8301126116d6578384fd5b8135818111156116e4578485fd5b8860208285010111156116f5578485fd5b95989497505060200194505050565b600060208284031215611715578081fd5b5035919050565b6000815180845260208085019450808401835b8381101561174b5781518752958201959082019060010161172f565b509495945050505050565b60006001600160a01b03808816835280871660208401525060a0604083015261178260a083018661171c565b8281036060840152611794818661171c565b9150508260808301529695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156117e85783516001600160a01b0316835292840192918401916001016117c3565b50909695505050505050565b602081526000611549602083018461171c565b604051601f8201601f1916810167ffffffffffffffff81118282101715611830576118306118b7565b604052919050565b6000821982111561184b5761184b6118a1565b500190565b600081600019048311821515161561186a5761186a6118a1565b500290565b600082821015611881576118816118a1565b500390565b600060001982141561189a5761189a6118a1565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fdfea2646970667358221220f8db2d67cf0444c299b7de6bebb4268a34d9a269c6294f6f15ae095d44cb232864736f6c63430008040033a264697066735822122092c4375c515c695d6f0f7e96b7635a65e1799e9d228a12932ddedc88a2bea41364736f6c63430008040033
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.