Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
HoldersRewardsDistributorV1
Compiler Version
v0.8.15+commit.e14f2714
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import "./HoldersRewardsDistributor.sol"; import "../utils/Transfers.sol"; import "../utils/InitializableAccessControl.sol"; /** * @title Bonding Curve Holder Reward Distributor * * @notice Holder reward distributor keeps track of every trade event happening in the curve, * and based on the amount of shares the holder has, alters the holders' reward weight, * which directly affects the amount of the distributed rewards between the holders * * @notice Holder reward distributor accepts the fees from the curve and distributes these fees * across shares holders proportionally to their weights * * @dev Apart from the `accept(uint256,address)` function designed to accept the fees from the * curve contract, the implementation must implement receive(), fallback(), and onTransferReceived() * functions to accept direct payments in both ETH and/or ERC20 payment token * * @dev receive() and onTransferReceived() with an empty data field must accept the fee in the same way * as an accept() function would do, but in a passive way (without ERC20 transfer) * * @dev The fallback() and onTransferReceived() with non-empty data field must accept the fee and the trading event; * trading event encoded in the bytes data field contains the information * on the trade which resulted in the fee being sent: * * - address trader - shares holder/trader * - bool isBuy - true if shares were bought, false if shares were sold * - uint256 sharesAmount - amount of shares bought or sold * * the values above are packed as data = abi.encode(trader, isBuy, sharesAmount) * and can be unpacked as (trader, isBuy, sharesAmount) = abi.decode(data, (address, bool, uint256)) * * if specified, the data field must be parsed by the implementation and its containing data applied; * standard logic applies, if the data is malformed implementation should throw * */ contract HoldersRewardsDistributorV1 is HoldersRewardsDistributor, InitializableAccessControl { // Info of each user. struct UserInfo { uint256 shares; uint256 rewardDebt; uint256 claimedAmount; uint256 unclaimedAmount; } // ERC20 payment token address address private /*immutable*/ paymentToken; /// bonding curve contract address address public sharesContractAddress; /// accumulated reward per share, times 1e18 (with 18 decimal precision) uint256 public accRewardPerShare; /// total number of share registered uint256 public totalShares; // Info of each user that stakes LP tokens. mapping(address => UserInfo) public userInfo; /** * @dev Deploys the distributor contract * * @param _owner contract, optional (can be zero address), since there are no admin functions * @param _sharesContractAddress TradeableShares contract to bind the distributor to, * optional (can be zero address), this can be set up later with the * `initializeSharesContractAddressIfRequired` function * @param _paymentToken ERC1363 payment token to bind to, optional (can be zero address), * zero address means distributor works with the plain ETH */ constructor(address _owner, address _sharesContractAddress, address _paymentToken) initializer { // initialize the deployed instance postConstruct(_owner, _sharesContractAddress, _paymentToken); } /** * @dev "Constructor replacement" for initializable, must be execute during or immediately after deployment * see https://docs.openzeppelin.com/upgrades-plugins/1.x/writing-upgradeable#initializers * * @param _owner contract, optional (can be zero address), since there are no admin functions * @param _sharesContractAddress TradeableShares contract to bind the distributor to, * optional (can be zero address), this can be set up later with the * `initializeSharesContractAddressIfRequired` function * @param _paymentToken ERC1363 payment token to bind to, optional (can be zero address), * zero address means distributor works with the plain ETH */ function postConstruct(address _owner, address _sharesContractAddress, address _paymentToken) public initializer { // execute parent initializer(s) _postConstruct(_owner); sharesContractAddress = _sharesContractAddress; paymentToken = _paymentToken; } /** * @notice Sets the TradeableShares contract to bind the distributor to * * @dev TradeableShares contract can be set only once; fails if it is already set * @param _sharesContractAddress TradeableShares contract to bind the distributor to */ function initializeSharesContractAddressIfRequired(address _sharesContractAddress) public { // check the address is not yet set require(sharesContractAddress == address(0) && _sharesContractAddress != address(0), "already initialized"); // set the TradeableShares contract address sharesContractAddress = _sharesContractAddress; } /** * @inheritdoc HoldersRewardsDistributor */ function getPaymentToken() public view returns (address) { return paymentToken; } /** * @dev Executed when TradeableShares contract notifies about shares bought event */ function __sharesBought(address _buyer, uint256 _amountBought) private { UserInfo storage userDetail = userInfo[_buyer]; if(userDetail.shares > 0) { // calculated pending reward if any uint256 pending = ((userDetail.shares * accRewardPerShare) / 1e18) - userDetail.rewardDebt; if(pending > 0) { // update unclaimed amount userDetail.unclaimedAmount += pending; } } // update state variables userDetail.shares += _amountBought; totalShares += _amountBought; userDetail.rewardDebt = (userDetail.shares * accRewardPerShare) / 1e18; } /** * @dev Executed when TradeableShares contract notifies about shares sold event */ function __sharesSold(address _seller, uint256 _amountSold) private { require(_amountSold <= userInfo[_seller].shares, "amount must be <= registered amount"); UserInfo storage userDetail = userInfo[_seller]; // calculated pending reward if any uint256 pending = ((userDetail.shares * accRewardPerShare) / 1e18) - userDetail.rewardDebt; if(pending > 0) { // update unclaimed amount userDetail.unclaimedAmount += pending; } // update state variables userDetail.shares = userDetail.shares - _amountSold; totalShares = totalShares - _amountSold; userDetail.rewardDebt = (userDetail.shares * accRewardPerShare) / 1e18; } /** * @dev Executed when TradeableShares contract send the fees; * @dev The very first tranche of the fees might be ignored if it is done by the issuer */ function __accept(uint256 _feeAmount) private { // check the state can accept the changes if(_feeAmount == 0 || totalShares == 0) { return; } // update state variables accRewardPerShare += (_feeAmount * 1e18) / totalShares; // emit an event emit FeeReceived(_feeAmount); } /** * @dev Processes the fee, and the sync message * * @dev Takes care about the encoded bytes data containing trader address, trade operation type, * and amount of the shares bought * * @dev Format: address | bool | uint256 */ function __parseTrade(uint256 _feeAmount, bytes memory data) private { if(totalShares == 0) { __parseFirstTrade(_feeAmount, data); } else { __parseNextTrade(_feeAmount, data); } } /** * @dev Processes the very first fee, and the sync message */ function __parseFirstTrade(uint256 _feeAmount, bytes memory data) private { // the very first sync message must not be empty require(data.length != 0, "sync message expected"); // verify message length require(data.length == 96, "malformed sync message"); // decode the sync message (address trader, bool isBuy, uint256 sharesAmount) = abi.decode(data, (address, bool, uint256)); // the very first operation can be buy only, and cannot be zero require(isBuy && sharesAmount >= 1, "invalid state"); // init: notify about the first share __sharesBought(trader, 1); // to save the gas execute the rest of the functions only if there is a need if(sharesAmount > 1) { // process the fee __accept(_feeAmount); // notify about the remaining shares __sharesBought(trader, sharesAmount - 1); } // emit an event emit SharesTraded(trader, true, sharesAmount); } /** * @dev Processes not the very first fee, and the sync message */ function __parseNextTrade(uint256 _feeAmount, bytes memory data) private { // process the fee __accept(_feeAmount); // if the sync message is empty, we're done if(data.length == 0) { return; } // verify message length require(data.length == 96, "malformed sync message"); // decode the sync message (address trader, bool isBuy, uint256 sharesAmount) = abi.decode(data, (address, bool, uint256)); if(isBuy) { // notify buy __sharesBought(trader, sharesAmount); } else { // notify sell __sharesSold(trader, sharesAmount); } // emit an event emit SharesTraded(trader, isBuy, sharesAmount); } /** * @inheritdoc HoldersRewardsDistributor */ function claimTheReward() public { uint256 claimableAmount = pendingReward(msg.sender); require(claimableAmount > 0, "Nothing to claim"); UserInfo storage userDetail = userInfo[msg.sender]; // update state variable userDetail.unclaimedAmount = 0; userDetail.claimedAmount += claimableAmount; userDetail.rewardDebt = (userDetail.shares * accRewardPerShare) / 1e18; // transfer reward if(paymentToken == address(0)) { Transfers.transfer(payable(msg.sender), claimableAmount); } else { require(ERC20(paymentToken).transfer(msg.sender, claimableAmount)); } // emit an event emit RewardClaimed(msg.sender, claimableAmount); } /** * @inheritdoc HoldersRewardsDistributor */ function pendingReward(address holder) public view returns (uint256) { // read user details and calculate how much we own UserInfo memory userDetail = userInfo[holder]; uint256 pending = userDetail.unclaimedAmount + userDetail.shares * accRewardPerShare / 1e18 - userDetail.rewardDebt; // get an idea of how much we have on the balance uint256 available = paymentToken == address(0)? address(this).balance: ERC20(paymentToken).balanceOf(address(this)); // we allow up to 1 gwei cumulative discrepancy due to rounding errors require(pending < 1_000_000_000 + available, "discrepancy error"); // return the amount we're actually able to return in `claimTheReward` return pending > available? available: pending; } /** * @inheritdoc ERC1363Receiver * * @notice Anyone can send some additional rewards – just use empty `data` for a callback * * @dev Non-empty `data` executes trade updates and therefore is restricted to be sent only * by `sharesContractAddress` */ function onTransferReceived(address operator, address, uint256 value, bytes memory data) public returns (bytes4) { require(msg.sender == paymentToken, "received event from wrong token"); require(operator == sharesContractAddress, "not allowed"); __parseTrade(value, data); return ERC1363Receiver(this).onTransferReceived.selector; } /** * @notice Receive is public. Anyone can send some additional rewards ;) */ receive() external payable { require(paymentToken == address(0), "not allowed"); __parseTrade(msg.value, bytes("")); } /** * @dev Fallback executes trade updates and therefore is restricted to be executed only by `sharesContractAddress` * * @notice If you want do donate some rewards - use `receive()` */ fallback() external payable { require(paymentToken == address(0), "not an ETH reward distributor"); require(msg.sender == sharesContractAddress, "not allowed"); __parseTrade(msg.value, msg.data); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (proxy/utils/Initializable.sol) pragma solidity ^0.8.0; import "../../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() initializer {} * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Modifier to protect an initializer function from being invoked twice. */ modifier initializer() { // If the contract is initializing we ignore whether _initialized is set in order to support multiple // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the // contract may have been reentered. require(_initializing ? _isConstructor() : !_initialized, "Initializable: contract is already initialized"); bool isTopLevelCall = !_initializing; if (isTopLevelCall) { _initializing = true; _initialized = true; } _; if (isTopLevelCall) { _initializing = false; } } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} modifier, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } function _isConstructor() private view returns (bool) { return !AddressUpgradeable.isContract(address(this)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Address.sol) pragma solidity ^0.8.0; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @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; 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"); (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"); (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"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal 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 assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import "../interfaces/ERC1363Spec.sol"; /** * @title Bonding Curve Holder Reward Distributor * * @notice Holder reward distributor keeps track of every trade event happening in the curve, * and based on the amount of shares the holder has, alters the holders' reward weight, * which directly affects the amount of the distributed rewards between the holders * * @notice Holder reward distributor accepts the fees from the curve and distributes these fees * across shares holders proportionally to their weights * * @dev Apart from the `accept(uint256,address)` function designed to accept the fees from the * curve contract, the implementation must implement receive(), fallback(), and onTransferReceived() * functions to accept direct payments in both ETH and/or ERC20 payment token * * @dev receive() and onTransferReceived() with an empty data field must accept the fee in the same way * as an accept() function would do, but in a passive way (without ERC20 transfer) * * @dev The fallback() and onTransferReceived() with non-empty data field must accept the fee and the trading event; * trading event encoded in the bytes data field contains the information * on the trade which resulted in the fee being sent: * * - address trader - shares holder/trader * - bool isBuy - true if shares were bought, false if shares were sold * - uint256 sharesAmount - amount of shares bought or sold * * the values above are packed as data = abi.encode(trader, isBuy, sharesAmount) * and can be unpacked as (trader, isBuy, sharesAmount) = abi.decode(data, (address, bool, uint256)) * * if specified, the data field must be parsed by the implementation and its containing data applied; * standard logic applies, if the data is malformed implementation should throw * */ interface HoldersRewardsDistributor is ERC1363Receiver { /** * @dev Fired in `sharesBought` and `sharesSold` * * @param trader is a buyer or a seller, depending on the operation type * @param isBuy true if the event comes from the `sharesBought` and represents the buy operation, * false if the event comes from the `sharesSold` and represents the sell operation * @param sharesAmount amount of the shares bought or sold (see `isBuy`) */ event SharesTraded(address indexed trader, bool indexed isBuy, uint256 sharesAmount); /** * @dev Fired when the fee for the distribution is received * * @param feeAmount amount of the fee to distribute between the holders */ event FeeReceived(uint256 feeAmount); /** * @dev Fired in `claimReward` * * @param holder address of the trader (and shares holder) who received the reward * @param rewardAmount amount of the reward sent */ event RewardClaimed(address indexed holder, uint256 rewardAmount); /** * @notice ERC20 payment token distributor is bound to * * @return paymentToken ERC20 payment token address the contract is bound to, * or zero zero address if it operates with the plain ETH */ function getPaymentToken() external view returns(address paymentToken); /* */ /** * @notice Notifies the distributor about the trade event * * @dev Trade amount specified affects holder's (buyer's) weight when calculating the reward * * @param buyer shares buyer (becomes shares holder if not yet), a.k.a trader * @param amountBought amount of the shares bought *//* function sharesBought(address buyer, uint256 amountBought) external; */ /** * @notice Notifies the distributor about the trade event * * @dev Trade amount specified affects holder's (seller's) weight when calculating the reward * * @param seller shares seller (shares holder), a.k.a trader * @param amountSold amount of the shares sold *//* function sharesSold(address seller, uint256 amountSold) external; */ /** * @notice Executed by the fee sender to send the fee; in case of the ERC20 payment, * this is the ask to take the specified amount of the ERC20 token of the specified type; * in case of the ETH payment, the amount must be supplied with the transaction itself * * @dev When paying with an ERC20 payment token, sender must approve the contract for * at least the amount specified before executing this function * * @dev Updates the accumulated reward per share * * @param feeAmount amount of the fee sent, * in the case of ETH payment must be equal to msg.value *//* function accept(uint256 feeAmount) external payable; */ /** * @notice Executed by the holder to claim entire pending reward * * @dev Holder can verify pending reward amount with the `pendingReward` function */ function claimTheReward() external; /** * @notice Pending (claimable) reward. This is the amount which can be claimed using `claimTheReward` * * @param holder the holder address to query the reward for * @return rewardAmount pending reward amount\ */ function pendingReward(address holder) external view returns(uint256 rewardAmount); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import "./ERC20Spec.sol"; import "./ERC165Spec.sol"; /** * @title ERC1363 Interface * * @dev Interface defining a ERC1363 Payable Token contract. * Implementing contracts MUST implement the ERC1363 interface as well as the ERC20 and ERC165 interfaces. */ interface ERC1363 is ERC20, ERC165 { /* * Note: the ERC-165 identifier for this interface is 0xb0202a11. * 0xb0202a11 === * bytes4(keccak256('transferAndCall(address,uint256)')) ^ * bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^ * bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^ * bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^ * bytes4(keccak256('approveAndCall(address,uint256)')) ^ * bytes4(keccak256('approveAndCall(address,uint256,bytes)')) */ /** * @notice Transfer tokens from `msg.sender` to another address and then call `onTransferReceived` on receiver * @param to address The address which you want to transfer to * @param value uint256 The amount of tokens to be transferred * @return true unless throwing */ function transferAndCall(address to, uint256 value) external returns (bool); /** * @notice Transfer tokens from `msg.sender` to another address and then call `onTransferReceived` on receiver * @param to address The address which you want to transfer to * @param value uint256 The amount of tokens to be transferred * @param data bytes Additional data with no specified format, sent in call to `to` * @return true unless throwing */ function transferAndCall(address to, uint256 value, bytes memory data) external returns (bool); /** * @notice Transfer tokens from one address to another and then call `onTransferReceived` on receiver * @param from address The address which you want to send tokens from * @param to address The address which you want to transfer to * @param value uint256 The amount of tokens to be transferred * @return true unless throwing */ function transferFromAndCall(address from, address to, uint256 value) external returns (bool); /** * @notice Transfer tokens from one address to another and then call `onTransferReceived` on receiver * @param from address The address which you want to send tokens from * @param to address The address which you want to transfer to * @param value uint256 The amount of tokens to be transferred * @param data bytes Additional data with no specified format, sent in call to `to` * @return true unless throwing */ function transferFromAndCall(address from, address to, uint256 value, bytes memory data) external returns (bool); /** * @notice Approve the passed address to spend the specified amount of tokens on behalf of msg.sender * and then call `onApprovalReceived` on spender. * @param spender address The address which will spend the funds * @param value uint256 The amount of tokens to be spent */ function approveAndCall(address spender, uint256 value) external returns (bool); /** * @notice Approve the passed address to spend the specified amount of tokens on behalf of msg.sender * and then call `onApprovalReceived` on spender. * @param spender address The address which will spend the funds * @param value uint256 The amount of tokens to be spent * @param data bytes Additional data with no specified format, sent in call to `spender` */ function approveAndCall(address spender, uint256 value, bytes memory data) external returns (bool); } /** * @title ERC1363Receiver Interface * * @dev Interface for any contract that wants to support `transferAndCall` or `transferFromAndCall` * from ERC1363 token contracts. */ interface ERC1363Receiver { /* * Note: the ERC-165 identifier for this interface is 0x88a7ca5c. * 0x88a7ca5c === bytes4(keccak256("onTransferReceived(address,address,uint256,bytes)")) */ /** * @notice Handle the receipt of ERC1363 tokens * * @dev Any ERC1363 smart contract calls this function on the recipient * after a `transfer` or a `transferFrom`. This function MAY throw to revert and reject the * transfer. Return of other than the magic value MUST result in the * transaction being reverted. * Note: the token contract address is always the message sender. * * @param operator address The address which called `transferAndCall` or `transferFromAndCall` function * @param from address The address which are token transferred from * @param value uint256 The amount of tokens transferred * @param data bytes Additional data with no specified format * @return `bytes4(keccak256("onTransferReceived(address,address,uint256,bytes)"))` * unless throwing */ function onTransferReceived(address operator, address from, uint256 value, bytes memory data) external returns (bytes4); } /** * @title ERC1363Spender Interface * * @dev Interface for any contract that wants to support `approveAndCall` * from ERC1363 token contracts. */ interface ERC1363Spender { /* * Note: the ERC-165 identifier for this interface is 0x7b04a2d0. * 0x7b04a2d0 === bytes4(keccak256("onApprovalReceived(address,uint256,bytes)")) */ /** * @notice Handle the approval of ERC1363 tokens * * @dev Any ERC1363 smart contract calls this function on the recipient * after an `approve`. This function MAY throw to revert and reject the * approval. Return of other than the magic value MUST result in the * transaction being reverted. * Note: the token contract address is always the message sender. * * @param owner address The address which called `approveAndCall` function * @param value uint256 The amount of tokens to be spent * @param data bytes Additional data with no specified format * @return `bytes4(keccak256("onApprovalReceived(address,uint256,bytes)"))` * unless throwing */ function onApprovalReceived(address owner, uint256 value, bytes memory data) external returns (bytes4); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; /** * @title ERC-165 Standard Interface Detection * * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * @dev Implementers can declare support of contract interfaces, * which can then be queried by others. * * @author Christian Reitwießner, Nick Johnson, Fabian Vogelsteller, Jordi Baylina, Konrad Feldmeier, William Entriken */ interface ERC165 { /** * @notice Query if a contract implements an interface * * @dev Interface identification is specified in ERC-165. * This function uses less than 30,000 gas. * * @param interfaceID The interface identifier, as specified in ERC-165 * @return `true` if the contract implements `interfaceID` and * `interfaceID` is not 0xffffffff, `false` otherwise */ function supportsInterface(bytes4 interfaceID) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; /** * @title EIP-20: ERC-20 Token Standard * * @notice The ERC-20 (Ethereum Request for Comments 20), proposed by Fabian Vogelsteller in November 2015, * is a Token Standard that implements an API for tokens within Smart Contracts. * * @notice It provides functionalities like to transfer tokens from one account to another, * to get the current token balance of an account and also the total supply of the token available on the network. * Besides these it also has some other functionalities like to approve that an amount of * token from an account can be spent by a third party account. * * @notice If a Smart Contract implements the following methods and events it can be called an ERC-20 Token * Contract and, once deployed, it will be responsible to keep track of the created tokens on Ethereum. * * @notice See https://ethereum.org/en/developers/docs/standards/tokens/erc-20/ * @notice See https://eips.ethereum.org/EIPS/eip-20 */ interface ERC20 { /** * @dev Fired in transfer(), transferFrom() to indicate that token transfer happened * * @param from an address tokens were consumed from * @param to an address tokens were sent to * @param value number of tokens transferred */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Fired in approve() to indicate an approval event happened * * @param owner an address which granted a permission to transfer * tokens on its behalf * @param spender an address which received a permission to transfer * tokens on behalf of the owner `_owner` * @param value amount of tokens granted to transfer on behalf */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @return name of the token (ex.: USD Coin) */ // OPTIONAL - This method can be used to improve usability, // but interfaces and other contracts MUST NOT expect these values to be present. // function name() external view returns (string memory); /** * @return symbol of the token (ex.: USDC) */ // OPTIONAL - This method can be used to improve usability, // but interfaces and other contracts MUST NOT expect these values to be present. // function symbol() external view returns (string memory); /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5,05` (`505 / 10 ** 2`). * * @dev Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless this function is * overridden; * * @dev NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. * * @return token decimals */ // OPTIONAL - This method can be used to improve usability, // but interfaces and other contracts MUST NOT expect these values to be present. // function decimals() external view returns (uint8); /** * @return the amount of tokens in existence */ function totalSupply() external view returns (uint256); /** * @notice Gets the balance of a particular address * * @param _owner the address to query the the balance for * @return balance an amount of tokens owned by the address specified */ function balanceOf(address _owner) external view returns (uint256 balance); /** * @notice Transfers some tokens to an external address or a smart contract * * @dev Called by token owner (an address which has a * positive token balance tracked by this smart contract) * @dev Throws on any error like * * insufficient token balance or * * incorrect `_to` address: * * zero address or * * self address or * * smart contract which doesn't support ERC20 * * @param _to an address to transfer tokens to, * must be either an external address or a smart contract, * compliant with the ERC20 standard * @param _value amount of tokens to be transferred,, zero * value is allowed * @return success true on success, throws otherwise */ function transfer(address _to, uint256 _value) external returns (bool success); /** * @notice Transfers some tokens on behalf of address `_from' (token owner) * to some other address `_to` * * @dev Called by token owner on his own or approved address, * an address approved earlier by token owner to * transfer some amount of tokens on its behalf * @dev Throws on any error like * * insufficient token balance or * * incorrect `_to` address: * * zero address or * * same as `_from` address (self transfer) * * smart contract which doesn't support ERC20 * * @param _from token owner which approved caller (transaction sender) * to transfer `_value` of tokens on its behalf * @param _to an address to transfer tokens to, * must be either an external address or a smart contract, * compliant with the ERC20 standard * @param _value amount of tokens to be transferred,, zero * value is allowed * @return success true on success, throws otherwise */ function transferFrom(address _from, address _to, uint256 _value) external returns (bool success); /** * @notice Approves address called `_spender` to transfer some amount * of tokens on behalf of the owner (transaction sender) * * @dev Transaction sender must not necessarily own any tokens to grant the permission * * @param _spender an address approved by the caller (token owner) * to spend some tokens on its behalf * @param _value an amount of tokens spender `_spender` is allowed to * transfer on behalf of the token owner * @return success true on success, throws otherwise */ function approve(address _spender, uint256 _value) external returns (bool success); /** * @notice Returns the amount which _spender is still allowed to withdraw from _owner. * * @dev A function to check an amount of tokens owner approved * to transfer on its behalf by some other address called "spender" * * @param _owner an address which approves transferring some tokens on its behalf * @param _spender an address approved to transfer some tokens on behalf * @return remaining an amount of tokens approved address `_spender` can transfer on behalf * of token owner `_owner` */ function allowance(address _owner, address _spender) external view returns (uint256 remaining); } /** * @title Mintable/burnable ERC20 Extension * * @notice Adds mint/burn functions to ERC20 interface, these functions * are usually present in ERC20 implementations, but these become * a must for the bridged tokens in L2 since the bridge on L2 * needs to have a way to mint tokens deposited from L1 to L2 * and to burn tokens to be withdrawn from L2 to L1 */ interface MintableBurnableERC20 is ERC20 { /** * @dev Mints (creates) some tokens to address specified * @dev The value specified is treated as is without taking * into account what `decimals` value is * * @param _to an address to mint tokens to * @param _value an amount of tokens to mint (create) */ function mint(address _to, uint256 _value) external; /** * @dev Burns (destroys) some tokens from the address specified * * @dev The value specified is treated as is without taking * into account what `decimals` value is * * @param _from an address to burn some tokens from * @param _value an amount of tokens to burn (destroy) */ function burn(address _from, uint256 _value) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.2; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; /** * @title Initializable Role-based Access Control (RBAC) // ERC1967Proxy * * @notice Access control smart contract provides an API to check * if a specific operation is permitted globally and/or * if a particular user has a permission to execute it. * * @notice This contract is inherited by other contracts requiring the role-based access control (RBAC) * protection for the restricted access functions * * @notice It deals with two main entities: features and roles. * * @notice Features are designed to be used to enable/disable public functions * of the smart contract (used by a wide audience). * @notice User roles are designed to control the access to restricted functions * of the smart contract (used by a limited set of maintainers). * * @notice Terms "role", "permissions" and "set of permissions" have equal meaning * in the documentation text and may be used interchangeably. * @notice Terms "permission", "single permission" implies only one permission bit set. * * @notice Access manager is a special role which allows to grant/revoke other roles. * Access managers can only grant/revoke permissions which they have themselves. * As an example, access manager with no other roles set can only grant/revoke its own * access manager permission and nothing else. * * @notice Access manager permission should be treated carefully, as a super admin permission: * Access manager with even no other permission can interfere with another account by * granting own access manager permission to it and effectively creating more powerful * permission set than its own. * * @dev Both current and OpenZeppelin AccessControl implementations feature a similar API * to check/know "who is allowed to do this thing". * @dev Zeppelin implementation is more flexible: * - it allows setting unlimited number of roles, while current is limited to 256 different roles * - it allows setting an admin for each role, while current allows having only one global admin * @dev Current implementation is more lightweight: * - it uses only 1 bit per role, while Zeppelin uses 256 bits * - it allows setting up to 256 roles at once, in a single transaction, while Zeppelin allows * setting only one role in a single transaction * * @dev This smart contract is designed to be inherited by other * smart contracts which require access control management capabilities. * * @dev Access manager permission has a bit 255 set. * This bit must not be used by inheriting contracts for any other permissions/features. * * @dev This is an initializable version of the RBAC, based on Zeppelin implementation, * it can be used for ERC1967 proxies, as well as for EIP-1167 minimal proxies * see https://docs.openzeppelin.com/contracts/4.x/upgradeable * see https://docs.openzeppelin.com/contracts/4.x/api/proxy#UUPSUpgradeable * see https://forum.openzeppelin.com/t/uups-proxies-tutorial-solidity-javascript/7786 * see https://eips.ethereum.org/EIPS/eip-1167 * see https://docs.openzeppelin.com/contracts/4.x/api/proxy#Clones * * @author Basil Gorin */ abstract contract InitializableAccessControl is Initializable { /** * @dev Privileged addresses with defined roles/permissions * @dev In the context of ERC20/ERC721 tokens these can be permissions to * allow minting or burning tokens, transferring on behalf and so on * * @dev Maps user address to the permissions bitmask (role), where each bit * represents a permission * @dev Bitmask 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF * represents all possible permissions * @dev 'This' address mapping represents global features of the smart contract * * @dev We keep the mapping private to prevent direct writes to it from the inheriting * contracts, `getRole()` and `updateRole()` functions should be used instead */ mapping(address => uint256) private userRoles; /** * @dev Empty reserved space in storage. The size of the __gap array is calculated so that * the amount of storage used by a contract always adds up to the 50. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; /** * @notice Access manager is responsible for assigning the roles to users, * enabling/disabling global features of the smart contract * @notice Access manager can add, remove and update user roles, * remove and update global features * * @dev Role ROLE_ACCESS_MANAGER allows modifying user roles and global features * @dev Role ROLE_ACCESS_MANAGER has single bit at position 255 enabled */ uint256 public constant ROLE_ACCESS_MANAGER = 0x8000000000000000000000000000000000000000000000000000000000000000; /** * @notice Upgrade manager is responsible for smart contract upgrades, * see https://docs.openzeppelin.com/contracts/4.x/api/proxy#UUPSUpgradeable * see https://docs.openzeppelin.com/contracts/4.x/upgradeable * * @dev Role ROLE_UPGRADE_MANAGER allows passing the _authorizeUpgrade() check * @dev Role ROLE_UPGRADE_MANAGER has single bit at position 254 enabled */ uint256 public constant ROLE_UPGRADE_MANAGER = 0x4000000000000000000000000000000000000000000000000000000000000000; /** * @dev Bitmask representing all the possible permissions (super admin role) * @dev Has all the bits are enabled (2^256 - 1 value) */ uint256 private constant FULL_PRIVILEGES_MASK = type(uint256).max; // before 0.8.0: uint256(-1) overflows to 0xFFFF... /** * @dev Fired in updateRole() and updateFeatures() * * @param operator address which was granted/revoked permissions * @param requested permissions requested * @param assigned permissions effectively set */ event RoleUpdated(address indexed operator, uint256 requested, uint256 assigned); /** * @notice Function modifier making a function defined as public behave as restricted * (so that only a pre-configured set of accounts can execute it) * * @param role the role transaction executor is required to have; * the function throws an "access denied" exception if this condition is not met */ modifier restrictedTo(uint256 role) { // verify the access permission require(isSenderInRole(role), "access denied"); // execute the rest of the function _; } /** * @dev Creates/deploys the ACL implementation to be used in a proxy * * @dev Note: * the implementation is already initialized and * `_postConstruct` is not executable on the implementation * `_postConstruct` is still available in the context of a proxy * and should be executed on the proxy deployment (in the same tx) */ // constructor() initializer {} /** * @dev Contract initializer, sets the contract owner to have full privileges * * @dev Can be executed only once, reverts when executed second time * * @dev IMPORTANT: * this function SHOULD be executed during proxy deployment (in the same transaction) * * @param _owner smart contract owner having full privileges */ function _postConstruct(address _owner) internal virtual onlyInitializing { // grant owner full privileges __setRole(_owner, FULL_PRIVILEGES_MASK, FULL_PRIVILEGES_MASK); } /** * @dev Highest version that has been initialized. * Non-zero value means contract was already initialized. * @dev see {Initializable}, {reinitializer}. * * @return highest version that has been initialized */ /* function getInitializedVersion() public view returns(uint64) { // delegate to `_getInitializedVersion` return _getInitializedVersion(); } */ /** * @notice Retrieves globally set of features enabled * * @dev Effectively reads userRoles role for the contract itself * * @return 256-bit bitmask of the features enabled */ function features() public view returns (uint256) { // features are stored in 'this' address mapping of `userRoles` return getRole(address(this)); } /** * @notice Updates set of the globally enabled features (`features`), * taking into account sender's permissions * * @dev Requires transaction sender to have `ROLE_ACCESS_MANAGER` permission * @dev Function is left for backward compatibility with older versions * * @param _mask bitmask representing a set of features to enable/disable */ function updateFeatures(uint256 _mask) public { // delegate call to `updateRole` updateRole(address(this), _mask); } /** * @notice Reads the permissions (role) for a given user from the `userRoles` mapping * (privileged addresses with defined roles/permissions) * @notice In the context of ERC20/ERC721 tokens these can be permissions to * allow minting or burning tokens, transferring on behalf and so on * * @dev Having a simple getter instead of making the mapping public * allows enforcing the encapsulation of the mapping and protects from * writing to it directly in the inheriting smart contracts * * @param operator address of a user to read permissions for, * or self address to read global features of the smart contract */ function getRole(address operator) public view returns(uint256) { // read the value from `userRoles` and return return userRoles[operator]; } /** * @notice Updates set of permissions (role) for a given user, * taking into account sender's permissions. * * @dev Setting role to zero is equivalent to removing an all permissions * @dev Setting role to `FULL_PRIVILEGES_MASK` is equivalent to * copying senders' permissions (role) to the user * @dev Requires transaction sender to have `ROLE_ACCESS_MANAGER` permission * * @param operator address of a user to alter permissions for, * or self address to alter global features of the smart contract * @param role bitmask representing a set of permissions to * enable/disable for a user specified */ function updateRole(address operator, uint256 role) public { // caller must have a permission to update user roles require(isSenderInRole(ROLE_ACCESS_MANAGER), "access denied"); // evaluate the role and reassign it __setRole(operator, role, _evaluateBy(msg.sender, getRole(operator), role)); } /** * @notice Determines the permission bitmask an operator can set on the * target permission set * @notice Used to calculate the permission bitmask to be set when requested * in `updateRole` and `updateFeatures` functions * * @dev Calculated based on: * 1) operator's own permission set read from userRoles[operator] * 2) target permission set - what is already set on the target * 3) desired permission set - what do we want set target to * * @dev Corner cases: * 1) Operator is super admin and its permission set is `FULL_PRIVILEGES_MASK`: * `desired` bitset is returned regardless of the `target` permission set value * (what operator sets is what they get) * 2) Operator with no permissions (zero bitset): * `target` bitset is returned regardless of the `desired` value * (operator has no authority and cannot modify anything) * * @dev Example: * Consider an operator with the permissions bitmask 00001111 * is about to modify the target permission set 01010101 * Operator wants to set that permission set to 00110011 * Based on their role, an operator has the permissions * to update only lowest 4 bits on the target, meaning that * high 4 bits of the target set in this example is left * unchanged and low 4 bits get changed as desired: 01010011 * * @param operator address of the contract operator which is about to set the permissions * @param target input set of permissions to operator is going to modify * @param desired desired set of permissions operator would like to set * @return resulting set of permissions given operator will set */ function _evaluateBy(address operator, uint256 target, uint256 desired) internal view returns (uint256) { // read operator's permissions uint256 p = getRole(operator); // taking into account operator's permissions, // 1) enable the permissions desired on the `target` target |= p & desired; // 2) disable the permissions desired on the `target` target &= FULL_PRIVILEGES_MASK ^ (p & (FULL_PRIVILEGES_MASK ^ desired)); // return calculated result return target; } /** * @notice Checks if requested set of features is enabled globally on the contract * * @param required set of features to check against * @return true if all the features requested are enabled, false otherwise */ function isFeatureEnabled(uint256 required) public view returns (bool) { // delegate call to `__hasRole`, passing `features` property return __hasRole(features(), required); } /** * @notice Checks if transaction sender `msg.sender` has all the permissions required * * @dev Used in smart contracts only. Off-chain clients should use `isOperatorInRole`. * * @param required set of permissions (role) to check against * @return true if all the permissions requested are enabled, false otherwise */ function isSenderInRole(uint256 required) public view returns (bool) { // delegate call to `isOperatorInRole`, passing transaction sender return isOperatorInRole(msg.sender, required); } /** * @notice Checks if operator has all the permissions (role) required * * @param operator address of the user to check role for * @param required set of permissions (role) to check * @return true if all the permissions requested are enabled, false otherwise */ function isOperatorInRole(address operator, uint256 required) public view returns (bool) { // delegate call to `__hasRole`, passing operator's permissions (role) return __hasRole(getRole(operator), required); } /** * @dev Sets the `assignedRole` role to the operator, logs both `requestedRole` and `actualRole` * * @dev Unsafe: * provides direct write access to `userRoles` mapping without any security checks, * doesn't verify the executor (msg.sender) permissions, * must be kept private at all times * * @param operator address of a user to alter permissions for, * or self address to alter global features of the smart contract * @param requestedRole bitmask representing a set of permissions requested * to be enabled/disabled for a user specified, used only to be logged into event * @param assignedRole bitmask representing a set of permissions to * enable/disable for a user specified, used to update the mapping and to be logged into event */ function __setRole(address operator, uint256 requestedRole, uint256 assignedRole) private { // assign the role to the operator userRoles[operator] = assignedRole; // fire an event emit RoleUpdated(operator, requestedRole, assignedRole); } /** * @dev Checks if role `actual` contains all the permissions required `required` * * @param actual existent role * @param required required role * @return true if actual has required role (all permissions), false otherwise */ function __hasRole(uint256 actual, uint256 required) private pure returns (bool) { // check the bitmask for the role required and return the result return actual & required == required; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; /** * @notice Replaces built-in Solidity address.transfer and address.send functions * with the address.call function */ library Transfers { /// @dev Mimics address.send forwarding 4,900 gas function send(address payable to, uint256 value) internal returns(bool) { (bool success, ) = to.call{gas: 4900, value: value}(""); return success; } /// @dev Mimics address.transfer forwarding 4,900 gas function transfer(address payable to, uint256 value) internal { require(send(to, value), "failed to send ether"); } /// @dev Alias for `send` function send1(address payable to, uint256 value) internal returns(bool) { return send(to, value); } /// @dev Alias for `transfer` function transfer1(address payable to, uint256 value) internal { transfer(to, value); } }
{ "evmVersion": "london", "libraries": {}, "metadata": { "bytecodeHash": "ipfs", "useLiteralContent": true }, "optimizer": { "enabled": true, "runs": 200 }, "remappings": [], "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_sharesContractAddress","type":"address"},{"internalType":"address","name":"_paymentToken","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"feeAmount","type":"uint256"}],"name":"FeeReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"holder","type":"address"},{"indexed":false,"internalType":"uint256","name":"rewardAmount","type":"uint256"}],"name":"RewardClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"uint256","name":"requested","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"assigned","type":"uint256"}],"name":"RoleUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"trader","type":"address"},{"indexed":true,"internalType":"bool","name":"isBuy","type":"bool"},{"indexed":false,"internalType":"uint256","name":"sharesAmount","type":"uint256"}],"name":"SharesTraded","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"ROLE_ACCESS_MANAGER","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ROLE_UPGRADE_MANAGER","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"accRewardPerShare","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimTheReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"features","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPaymentToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"getRole","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_sharesContractAddress","type":"address"}],"name":"initializeSharesContractAddressIfRequired","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"required","type":"uint256"}],"name":"isFeatureEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"required","type":"uint256"}],"name":"isOperatorInRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"required","type":"uint256"}],"name":"isSenderInRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onTransferReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"holder","type":"address"}],"name":"pendingReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_sharesContractAddress","type":"address"},{"internalType":"address","name":"_paymentToken","type":"address"}],"name":"postConstruct","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sharesContractAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mask","type":"uint256"}],"name":"updateFeatures","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"role","type":"uint256"}],"name":"updateRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userInfo","outputs":[{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"uint256","name":"rewardDebt","type":"uint256"},{"internalType":"uint256","name":"claimedAmount","type":"uint256"},{"internalType":"uint256","name":"unclaimedAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60806040523480156200001157600080fd5b50604051620018503803806200185083398101604081905262000034916200030c565b600054610100900460ff16620000515760005460ff16156200005b565b6200005b62000100565b620000b35760405162461bcd60e51b815260206004820152602e60248201526000805160206200183083398151915260448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b600054610100900460ff16158015620000d6576000805461ffff19166101011790555b620000e38484846200011e565b8015620000f6576000805461ff00191690555b5050505062000356565b600062000118306200021060201b62000b481760201c565b15905090565b600054610100900460ff166200013b5760005460ff161562000145565b6200014562000100565b620001995760405162461bcd60e51b815260206004820152602e60248201526000805160206200183083398151915260448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401620000aa565b600054610100900460ff16158015620001bc576000805461ffff19166101011790555b620001c78462000216565b603480546001600160a01b038086166001600160a01b031992831617909255603380549285169290911691909117905580156200020a576000805461ff00191690555b50505050565b3b151590565b600054610100900460ff16620002835760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401620000aa565b62000292816000198062000295565b50565b6001600160a01b03831660008181526001602090815260409182902084905581518581529081018490527fe9be537308880e0f56b7d7cfd7abf85f14c4934486d138f848b92a0cbaf659b4910160405180910390a2505050565b80516001600160a01b03811681146200030757600080fd5b919050565b6000806000606084860312156200032257600080fd5b6200032d84620002ef565b92506200033d60208501620002ef565b91506200034d60408501620002ef565b90509250925092565b6114ca80620003666000396000f3fe6080604052600436106101185760003560e01c8063ae60bda4116100a0578063d7380ea611610064578063d7380ea61461046e578063e023fd4214610483578063e7db4d81146104a3578063f40f0f52146104c3578063fcc2c078146104e35761016a565b8063ae60bda4146103cc578063ae682e2e146103e4578063c688d693146103fc578063d41c3a651461041c578063d5bb7f671461044e5761016a565b8063725f3626116100e7578063725f36261461030d57806388a7ca5c1461033d578063939d6237146103765780639ba81bed1461038c578063ae5b102e146103ac5761016a565b80631959a0021461022e5780632b521416146102955780633a98ef39146102c157806344276733146102d75761016a565b3661016a576033546001600160a01b03161561014f5760405162461bcd60e51b8152600401610146906111aa565b60405180910390fd5b6101683460405180602001604052806000815250610503565b005b6033546001600160a01b0316156101c35760405162461bcd60e51b815260206004820152601d60248201527f6e6f7420616e2045544820726577617264206469737472696275746f720000006044820152606401610146565b6034546001600160a01b031633146101ed5760405162461bcd60e51b8152600401610146906111aa565b610168346000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061050392505050565b34801561023a57600080fd5b506102706102493660046111e4565b60376020526000908152604090208054600182015460028301546003909301549192909184565b6040805194855260208501939093529183015260608201526080015b60405180910390f35b3480156102a157600080fd5b50306000908152600160205260409020545b60405190815260200161028c565b3480156102cd57600080fd5b506102b360365481565b3480156102e357600080fd5b506102b36102f23660046111e4565b6001600160a01b031660009081526001602052604090205490565b34801561031957600080fd5b5061032d610328366004611201565b610525565b604051901515815260200161028c565b34801561034957600080fd5b5061035d610358366004611230565b610547565b6040516001600160e01b0319909116815260200161028c565b34801561038257600080fd5b506102b360355481565b34801561039857600080fd5b506101686103a73660046111e4565b6105ec565b3480156103b857600080fd5b506101686103c7366004611310565b610671565b3480156103d857600080fd5b506102b3600160fe1b81565b3480156103f057600080fd5b506102b3600160ff1b81565b34801561040857600080fd5b5061032d610417366004611310565b610716565b34801561042857600080fd5b506033546001600160a01b03165b6040516001600160a01b03909116815260200161028c565b34801561045a57600080fd5b50610168610469366004611201565b61073f565b34801561047a57600080fd5b5061016861074c565b34801561048f57600080fd5b5061016861049e36600461133c565b6108c9565b3480156104af57600080fd5b50603454610436906001600160a01b031681565b3480156104cf57600080fd5b506102b36104de3660046111e4565b6109be565b3480156104ef57600080fd5b5061032d6104fe366004611201565b610b3c565b60365460000361051b576105178282610b4e565b5050565b6105178282610cc4565b30600090815260016020526040812054610541905b8316831490565b92915050565b6033546000906001600160a01b031633146105a45760405162461bcd60e51b815260206004820152601f60248201527f7265636569766564206576656e742066726f6d2077726f6e6720746f6b656e006044820152606401610146565b6034546001600160a01b038681169116146105d15760405162461bcd60e51b8152600401610146906111aa565b6105db8383610503565b50632229f29760e21b949350505050565b6034546001600160a01b031615801561060d57506001600160a01b03811615155b61064f5760405162461bcd60e51b8152602060048201526013602482015272185b1c9958591e481a5b9a5d1a585b1a5e9959606a1b6044820152606401610146565b603480546001600160a01b0319166001600160a01b0392909216919091179055565b61067e600160ff1b610b3c565b6106ba5760405162461bcd60e51b815260206004820152600d60248201526c1858d8d95cdcc819195b9a5959609a1b6044820152606401610146565b6105178282610711336106e2876001600160a01b031660009081526001602052604090205490565b6001600160a01b0391909116600090815260016020526040902054600019808818821618908716919091171690565b610da0565b6001600160a01b0382166000908152600160205260408120546107389061053a565b9392505050565b6107493082610671565b50565b6000610757336109be565b90506000811161079c5760405162461bcd60e51b815260206004820152601060248201526f4e6f7468696e6720746f20636c61696d60801b6044820152606401610146565b33600090815260376020526040812060038101829055600281018054919284926107c790849061139d565b90915550506035548154670de0b6b3a7640000916107e4916113b5565b6107ee91906113d4565b60018201556033546001600160a01b03166108125761080d3383610dfa565b610890565b60335460405163a9059cbb60e01b8152336004820152602481018490526001600160a01b039091169063a9059cbb906044016020604051808303816000875af1158015610863573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610887919061140b565b61089057600080fd5b60405182815233907f106f923f993c2149d49b4255ff723acafa1f2d94393f561d3eda32ae348f72419060200160405180910390a25050565b600054610100900460ff166108e45760005460ff16156108e8565b303b155b61094b5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610146565b600054610100900460ff1615801561096d576000805461ffff19166101011790555b61097684610e47565b603480546001600160a01b038086166001600160a01b031992831617909255603380549285169290911691909117905580156109b8576000805461ff00191690555b50505050565b6001600160a01b03811660009081526037602090815260408083208151608081018352815480825260018301549482018590526002830154938201939093526003909101546060820152603554909284929091670de0b6b3a764000091610a2591906113b5565b610a2f91906113d4565b8360600151610a3e919061139d565b610a489190611426565b6033549091506000906001600160a01b031615610ad0576033546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015610aa7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610acb919061143d565b610ad2565b475b9050610ae281633b9aca0061139d565b8210610b245760405162461bcd60e51b81526020600482015260116024820152703234b9b1b932b830b731bc9032b93937b960791b6044820152606401610146565b808211610b315781610b33565b805b95945050505050565b60006105413383610716565b3b151590565b8051600003610b975760405162461bcd60e51b81526020600482015260156024820152741cde5b98c81b595cdcd859d948195e1c1958dd1959605a1b6044820152606401610146565b8051606014610be15760405162461bcd60e51b81526020600482015260166024820152756d616c666f726d65642073796e63206d65737361676560501b6044820152606401610146565b600080600083806020019051810190610bfa9190611456565b925092509250818015610c0e575060018110155b610c4a5760405162461bcd60e51b815260206004820152600d60248201526c696e76616c696420737461746560981b6044820152606401610146565b610c55836001610ebf565b6001811115610c7b57610c6785610f96565b610c7b83610c76600184611426565b610ebf565b6040518181526001906001600160a01b038516907fbd737de9fda35bf54b4f4a52ea425f0d646b85bafdc736be7fd40cc50dd9ed92906020015b60405180910390a35050505050565b610ccd82610f96565b8051600003610cda575050565b8051606014610d245760405162461bcd60e51b81526020600482015260166024820152756d616c666f726d65642073796e63206d65737361676560501b6044820152606401610146565b600080600083806020019051810190610d3d9190611456565b9250925092508115610d5857610d538382610ebf565b610d62565b610d628382611016565b811515836001600160a01b03167fbd737de9fda35bf54b4f4a52ea425f0d646b85bafdc736be7fd40cc50dd9ed9283604051610cb591815260200190565b6001600160a01b03831660008181526001602090815260409182902084905581518581529081018490527fe9be537308880e0f56b7d7cfd7abf85f14c4934486d138f848b92a0cbaf659b4910160405180910390a2505050565b610e048282611148565b6105175760405162461bcd60e51b81526020600482015260146024820152733330b4b632b2103a379039b2b7321032ba3432b960611b6044820152606401610146565b600054610100900460ff16610eb25760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610146565b6107498160001980610da0565b6001600160a01b0382166000908152603760205260409020805415610f385760008160010154670de0b6b3a76400006035548460000154610f0091906113b5565b610f0a91906113d4565b610f149190611426565b90508015610f365780826003016000828254610f30919061139d565b90915550505b505b81816000016000828254610f4c919061139d565b925050819055508160366000828254610f65919061139d565b90915550506035548154670de0b6b3a764000091610f82916113b5565b610f8c91906113d4565b6001909101555050565b801580610fa35750603654155b15610fab5750565b603654610fc082670de0b6b3a76400006113b5565b610fca91906113d4565b60356000828254610fdb919061139d565b90915550506040518181527f86c46efee0a638b418fa0952cd587c78b75b8bc989e7a7c13a86d448ec34a0849060200160405180910390a150565b6001600160a01b03821660009081526037602052604090205481111561108a5760405162461bcd60e51b815260206004820152602360248201527f616d6f756e74206d757374206265203c3d207265676973746572656420616d6f6044820152621d5b9d60ea1b6064820152608401610146565b6001600160a01b038216600090815260376020526040812060018101546035548254929392670de0b6b3a7640000916110c2916113b5565b6110cc91906113d4565b6110d69190611426565b905080156110f857808260030160008282546110f2919061139d565b90915550505b8154611105908490611426565b8255603654611115908490611426565b6036556035548254670de0b6b3a764000091611130916113b5565b61113a91906113d4565b826001018190555050505050565b600080836001600160a01b031661132484604051600060405180830381858888f193505050503d806000811461119a576040519150601f19603f3d011682016040523d82523d6000602084013e61119f565b606091505b509095945050505050565b6020808252600b908201526a1b9bdd08185b1b1bddd95960aa1b604082015260600190565b6001600160a01b038116811461074957600080fd5b6000602082840312156111f657600080fd5b8135610738816111cf565b60006020828403121561121357600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b6000806000806080858703121561124657600080fd5b8435611251816111cf565b93506020850135611261816111cf565b925060408501359150606085013567ffffffffffffffff8082111561128557600080fd5b818701915087601f83011261129957600080fd5b8135818111156112ab576112ab61121a565b604051601f8201601f19908116603f011681019083821181831017156112d3576112d361121a565b816040528281528a60208487010111156112ec57600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b6000806040838503121561132357600080fd5b823561132e816111cf565b946020939093013593505050565b60008060006060848603121561135157600080fd5b833561135c816111cf565b9250602084013561136c816111cf565b9150604084013561137c816111cf565b809150509250925092565b634e487b7160e01b600052601160045260246000fd5b600082198211156113b0576113b0611387565b500190565b60008160001904831182151516156113cf576113cf611387565b500290565b6000826113f157634e487b7160e01b600052601260045260246000fd5b500490565b8051801515811461140657600080fd5b919050565b60006020828403121561141d57600080fd5b610738826113f6565b60008282101561143857611438611387565b500390565b60006020828403121561144f57600080fd5b5051919050565b60008060006060848603121561146b57600080fd5b8351611476816111cf565b9250611484602085016113f6565b915060408401519050925092509256fea264697066735822122036feda829a13929b76cc8895119347a0e3d1ac17b0ed9ee943ba44c0833e727364736f6c634300080f0033496e697469616c697a61626c653a20636f6e747261637420697320616c726561000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x6080604052600436106101185760003560e01c8063ae60bda4116100a0578063d7380ea611610064578063d7380ea61461046e578063e023fd4214610483578063e7db4d81146104a3578063f40f0f52146104c3578063fcc2c078146104e35761016a565b8063ae60bda4146103cc578063ae682e2e146103e4578063c688d693146103fc578063d41c3a651461041c578063d5bb7f671461044e5761016a565b8063725f3626116100e7578063725f36261461030d57806388a7ca5c1461033d578063939d6237146103765780639ba81bed1461038c578063ae5b102e146103ac5761016a565b80631959a0021461022e5780632b521416146102955780633a98ef39146102c157806344276733146102d75761016a565b3661016a576033546001600160a01b03161561014f5760405162461bcd60e51b8152600401610146906111aa565b60405180910390fd5b6101683460405180602001604052806000815250610503565b005b6033546001600160a01b0316156101c35760405162461bcd60e51b815260206004820152601d60248201527f6e6f7420616e2045544820726577617264206469737472696275746f720000006044820152606401610146565b6034546001600160a01b031633146101ed5760405162461bcd60e51b8152600401610146906111aa565b610168346000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061050392505050565b34801561023a57600080fd5b506102706102493660046111e4565b60376020526000908152604090208054600182015460028301546003909301549192909184565b6040805194855260208501939093529183015260608201526080015b60405180910390f35b3480156102a157600080fd5b50306000908152600160205260409020545b60405190815260200161028c565b3480156102cd57600080fd5b506102b360365481565b3480156102e357600080fd5b506102b36102f23660046111e4565b6001600160a01b031660009081526001602052604090205490565b34801561031957600080fd5b5061032d610328366004611201565b610525565b604051901515815260200161028c565b34801561034957600080fd5b5061035d610358366004611230565b610547565b6040516001600160e01b0319909116815260200161028c565b34801561038257600080fd5b506102b360355481565b34801561039857600080fd5b506101686103a73660046111e4565b6105ec565b3480156103b857600080fd5b506101686103c7366004611310565b610671565b3480156103d857600080fd5b506102b3600160fe1b81565b3480156103f057600080fd5b506102b3600160ff1b81565b34801561040857600080fd5b5061032d610417366004611310565b610716565b34801561042857600080fd5b506033546001600160a01b03165b6040516001600160a01b03909116815260200161028c565b34801561045a57600080fd5b50610168610469366004611201565b61073f565b34801561047a57600080fd5b5061016861074c565b34801561048f57600080fd5b5061016861049e36600461133c565b6108c9565b3480156104af57600080fd5b50603454610436906001600160a01b031681565b3480156104cf57600080fd5b506102b36104de3660046111e4565b6109be565b3480156104ef57600080fd5b5061032d6104fe366004611201565b610b3c565b60365460000361051b576105178282610b4e565b5050565b6105178282610cc4565b30600090815260016020526040812054610541905b8316831490565b92915050565b6033546000906001600160a01b031633146105a45760405162461bcd60e51b815260206004820152601f60248201527f7265636569766564206576656e742066726f6d2077726f6e6720746f6b656e006044820152606401610146565b6034546001600160a01b038681169116146105d15760405162461bcd60e51b8152600401610146906111aa565b6105db8383610503565b50632229f29760e21b949350505050565b6034546001600160a01b031615801561060d57506001600160a01b03811615155b61064f5760405162461bcd60e51b8152602060048201526013602482015272185b1c9958591e481a5b9a5d1a585b1a5e9959606a1b6044820152606401610146565b603480546001600160a01b0319166001600160a01b0392909216919091179055565b61067e600160ff1b610b3c565b6106ba5760405162461bcd60e51b815260206004820152600d60248201526c1858d8d95cdcc819195b9a5959609a1b6044820152606401610146565b6105178282610711336106e2876001600160a01b031660009081526001602052604090205490565b6001600160a01b0391909116600090815260016020526040902054600019808818821618908716919091171690565b610da0565b6001600160a01b0382166000908152600160205260408120546107389061053a565b9392505050565b6107493082610671565b50565b6000610757336109be565b90506000811161079c5760405162461bcd60e51b815260206004820152601060248201526f4e6f7468696e6720746f20636c61696d60801b6044820152606401610146565b33600090815260376020526040812060038101829055600281018054919284926107c790849061139d565b90915550506035548154670de0b6b3a7640000916107e4916113b5565b6107ee91906113d4565b60018201556033546001600160a01b03166108125761080d3383610dfa565b610890565b60335460405163a9059cbb60e01b8152336004820152602481018490526001600160a01b039091169063a9059cbb906044016020604051808303816000875af1158015610863573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610887919061140b565b61089057600080fd5b60405182815233907f106f923f993c2149d49b4255ff723acafa1f2d94393f561d3eda32ae348f72419060200160405180910390a25050565b600054610100900460ff166108e45760005460ff16156108e8565b303b155b61094b5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610146565b600054610100900460ff1615801561096d576000805461ffff19166101011790555b61097684610e47565b603480546001600160a01b038086166001600160a01b031992831617909255603380549285169290911691909117905580156109b8576000805461ff00191690555b50505050565b6001600160a01b03811660009081526037602090815260408083208151608081018352815480825260018301549482018590526002830154938201939093526003909101546060820152603554909284929091670de0b6b3a764000091610a2591906113b5565b610a2f91906113d4565b8360600151610a3e919061139d565b610a489190611426565b6033549091506000906001600160a01b031615610ad0576033546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015610aa7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610acb919061143d565b610ad2565b475b9050610ae281633b9aca0061139d565b8210610b245760405162461bcd60e51b81526020600482015260116024820152703234b9b1b932b830b731bc9032b93937b960791b6044820152606401610146565b808211610b315781610b33565b805b95945050505050565b60006105413383610716565b3b151590565b8051600003610b975760405162461bcd60e51b81526020600482015260156024820152741cde5b98c81b595cdcd859d948195e1c1958dd1959605a1b6044820152606401610146565b8051606014610be15760405162461bcd60e51b81526020600482015260166024820152756d616c666f726d65642073796e63206d65737361676560501b6044820152606401610146565b600080600083806020019051810190610bfa9190611456565b925092509250818015610c0e575060018110155b610c4a5760405162461bcd60e51b815260206004820152600d60248201526c696e76616c696420737461746560981b6044820152606401610146565b610c55836001610ebf565b6001811115610c7b57610c6785610f96565b610c7b83610c76600184611426565b610ebf565b6040518181526001906001600160a01b038516907fbd737de9fda35bf54b4f4a52ea425f0d646b85bafdc736be7fd40cc50dd9ed92906020015b60405180910390a35050505050565b610ccd82610f96565b8051600003610cda575050565b8051606014610d245760405162461bcd60e51b81526020600482015260166024820152756d616c666f726d65642073796e63206d65737361676560501b6044820152606401610146565b600080600083806020019051810190610d3d9190611456565b9250925092508115610d5857610d538382610ebf565b610d62565b610d628382611016565b811515836001600160a01b03167fbd737de9fda35bf54b4f4a52ea425f0d646b85bafdc736be7fd40cc50dd9ed9283604051610cb591815260200190565b6001600160a01b03831660008181526001602090815260409182902084905581518581529081018490527fe9be537308880e0f56b7d7cfd7abf85f14c4934486d138f848b92a0cbaf659b4910160405180910390a2505050565b610e048282611148565b6105175760405162461bcd60e51b81526020600482015260146024820152733330b4b632b2103a379039b2b7321032ba3432b960611b6044820152606401610146565b600054610100900460ff16610eb25760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610146565b6107498160001980610da0565b6001600160a01b0382166000908152603760205260409020805415610f385760008160010154670de0b6b3a76400006035548460000154610f0091906113b5565b610f0a91906113d4565b610f149190611426565b90508015610f365780826003016000828254610f30919061139d565b90915550505b505b81816000016000828254610f4c919061139d565b925050819055508160366000828254610f65919061139d565b90915550506035548154670de0b6b3a764000091610f82916113b5565b610f8c91906113d4565b6001909101555050565b801580610fa35750603654155b15610fab5750565b603654610fc082670de0b6b3a76400006113b5565b610fca91906113d4565b60356000828254610fdb919061139d565b90915550506040518181527f86c46efee0a638b418fa0952cd587c78b75b8bc989e7a7c13a86d448ec34a0849060200160405180910390a150565b6001600160a01b03821660009081526037602052604090205481111561108a5760405162461bcd60e51b815260206004820152602360248201527f616d6f756e74206d757374206265203c3d207265676973746572656420616d6f6044820152621d5b9d60ea1b6064820152608401610146565b6001600160a01b038216600090815260376020526040812060018101546035548254929392670de0b6b3a7640000916110c2916113b5565b6110cc91906113d4565b6110d69190611426565b905080156110f857808260030160008282546110f2919061139d565b90915550505b8154611105908490611426565b8255603654611115908490611426565b6036556035548254670de0b6b3a764000091611130916113b5565b61113a91906113d4565b826001018190555050505050565b600080836001600160a01b031661132484604051600060405180830381858888f193505050503d806000811461119a576040519150601f19603f3d011682016040523d82523d6000602084013e61119f565b606091505b509095945050505050565b6020808252600b908201526a1b9bdd08185b1b1bddd95960aa1b604082015260600190565b6001600160a01b038116811461074957600080fd5b6000602082840312156111f657600080fd5b8135610738816111cf565b60006020828403121561121357600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b6000806000806080858703121561124657600080fd5b8435611251816111cf565b93506020850135611261816111cf565b925060408501359150606085013567ffffffffffffffff8082111561128557600080fd5b818701915087601f83011261129957600080fd5b8135818111156112ab576112ab61121a565b604051601f8201601f19908116603f011681019083821181831017156112d3576112d361121a565b816040528281528a60208487010111156112ec57600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b6000806040838503121561132357600080fd5b823561132e816111cf565b946020939093013593505050565b60008060006060848603121561135157600080fd5b833561135c816111cf565b9250602084013561136c816111cf565b9150604084013561137c816111cf565b809150509250925092565b634e487b7160e01b600052601160045260246000fd5b600082198211156113b0576113b0611387565b500190565b60008160001904831182151516156113cf576113cf611387565b500290565b6000826113f157634e487b7160e01b600052601260045260246000fd5b500490565b8051801515811461140657600080fd5b919050565b60006020828403121561141d57600080fd5b610738826113f6565b60008282101561143857611438611387565b500390565b60006020828403121561144f57600080fd5b5051919050565b60008060006060848603121561146b57600080fd5b8351611476816111cf565b9250611484602085016113f6565b915060408401519050925092509256fea264697066735822122036feda829a13929b76cc8895119347a0e3d1ac17b0ed9ee943ba44c0833e727364736f6c634300080f0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _owner (address): 0x0000000000000000000000000000000000000000
Arg [1] : _sharesContractAddress (address): 0x0000000000000000000000000000000000000000
Arg [2] : _paymentToken (address): 0x0000000000000000000000000000000000000000
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000000
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 35 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.