Overview
ETH Balance
0 ETH
Eth Value
$0.00Token Holdings
More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 1,089 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Withdraw | 21246934 | 9 days ago | IN | 0 ETH | 0.00084798 | ||||
Unstake | 21246925 | 9 days ago | IN | 0 ETH | 0.00082249 | ||||
Rebalance | 19858951 | 203 days ago | IN | 0 ETH | 0.00021724 | ||||
Rebalance | 19808167 | 210 days ago | IN | 0 ETH | 0.00034648 | ||||
Rebalance | 19808164 | 210 days ago | IN | 0 ETH | 0.00027786 | ||||
Withdraw | 19722020 | 222 days ago | IN | 0 ETH | 0.00060073 | ||||
Unstake | 19721940 | 222 days ago | IN | 0 ETH | 0.00054643 | ||||
Rebalance | 19603124 | 239 days ago | IN | 0 ETH | 0.00106237 | ||||
Rebalance | 19410200 | 266 days ago | IN | 0 ETH | 0.00250785 | ||||
Unstake | 19407576 | 266 days ago | IN | 0 ETH | 0.0042952 | ||||
Rebalance | 19361188 | 273 days ago | IN | 0 ETH | 0.00516977 | ||||
Withdraw | 19357425 | 273 days ago | IN | 0 ETH | 0.00342736 | ||||
Unstake | 19357418 | 273 days ago | IN | 0 ETH | 0.0033238 | ||||
Withdraw | 19341869 | 275 days ago | IN | 0 ETH | 0.00447583 | ||||
Unstake | 19341861 | 275 days ago | IN | 0 ETH | 0.00401883 | ||||
Rebalance | 19159374 | 301 days ago | IN | 0 ETH | 0.00071901 | ||||
Rebalance | 19010640 | 322 days ago | IN | 0 ETH | 0.00134975 | ||||
Rebalance | 19010634 | 322 days ago | IN | 0 ETH | 0.00105486 | ||||
Withdraw | 18988176 | 325 days ago | IN | 0 ETH | 0.00072769 | ||||
Unstake | 18988171 | 325 days ago | IN | 0 ETH | 0.00098095 | ||||
Rebalance | 18987593 | 325 days ago | IN | 0 ETH | 0.00153797 | ||||
Withdraw | 18807639 | 350 days ago | IN | 0 ETH | 0.00210451 | ||||
Unstake | 18807633 | 350 days ago | IN | 0 ETH | 0.00214217 | ||||
Withdraw | 18627988 | 375 days ago | IN | 0 ETH | 0.00208567 | ||||
Withdraw | 18535550 | 388 days ago | IN | 0 ETH | 0.01004652 |
Loading...
Loading
Minimal Proxy Contract for 0x3f9a0b1a0b81473e051a26a039f730b28f02018b
Contract Name:
StakingPoolImpl
Compiler Version
v0.8.7+commit.e28d00a7
Contract Source Code (Solidity Standard Json-Input format)
// Copyright 2021 Cartesi Pte. Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); you may not use // this file except in compliance with the License. You may obtain a copy of the // License at http://www.apache.org/licenses/LICENSE-2.0 // Unless required by applicable law or agreed to in writing, software distributed // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR // CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. pragma solidity ^0.8.0; import "./interfaces/StakingPool.sol"; import "./StakingPoolData.sol"; import "./StakingPoolManagementImpl.sol"; import "./StakingPoolProducerImpl.sol"; import "./StakingPoolStakingImpl.sol"; import "./StakingPoolUserImpl.sol"; import "./StakingPoolWorkerImpl.sol"; contract StakingPoolImpl is StakingPool, StakingPoolData, StakingPoolManagementImpl, StakingPoolProducerImpl, StakingPoolStakingImpl, StakingPoolUserImpl, StakingPoolWorkerImpl { constructor( address _ctsi, address _staking, address _workerManager, address _ens, uint256 _stakeLock ) StakingPoolManagementImpl(_ens) StakingPoolProducerImpl(_ctsi) StakingPoolStakingImpl(_ctsi, _staking) StakingPoolUserImpl(_ctsi, _stakeLock) StakingPoolWorkerImpl(_workerManager) {} function initialize(address _fee, address _pos) external override initializer { __Pausable_init(); __Ownable_init(); __StakingPoolProducer_init(_fee, _pos); __StakingPoolStaking_init(); __StakingPoolManagementImpl_init(); } /// @notice updates the internal settings for important pieces of the Cartesi PoS system function update() external override onlyOwner { address _pos = factory.getPoS(); __StakingPoolWorkerImpl_update(_pos); } function transferOwnership(address newOwner) public override(StakingPool, OwnableUpgradeable) { OwnableUpgradeable.transferOwnership(newOwner); } }
// Copyright 2021 Cartesi Pte. Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); you may not use // this file except in compliance with the License. You may obtain a copy of the // License at http://www.apache.org/licenses/LICENSE-2.0 // Unless required by applicable law or agreed to in writing, software distributed // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR // CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. /// @title Interface PoS pragma solidity >=0.7.0 <0.9.0; interface IPoS { /// @notice Produce a block /// @param _index the index of the instance of pos you want to interact with /// @dev this function can only be called by a worker, user never calls it directly function produceBlock(uint256 _index) external returns (bool); /// @notice Get reward manager address /// @param _index index of instance /// @return address of instance's RewardManager function getRewardManagerAddress(uint256 _index) external view returns (address); /// @notice Get block selector address /// @param _index index of instance /// @return address of instance's block selector function getBlockSelectorAddress(uint256 _index) external view returns (address); /// @notice Get block selector index /// @param _index index of instance /// @return index of instance's block selector function getBlockSelectorIndex(uint256 _index) external view returns (uint256); /// @notice Get staking address /// @param _index index of instance /// @return address of instance's staking contract function getStakingAddress(uint256 _index) external view returns (address); /// @notice Get state of a particular instance /// @param _index index of instance /// @param _user address of user /// @return bool if user is eligible to produce next block /// @return address of user that was chosen to build the block /// @return current reward paid by the network for that block function getState(uint256 _index, address _user) external view returns ( bool, address, uint256 ); function terminate(uint256 _index) external; }
// Copyright 2021 Cartesi Pte. Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); you may not use // this file except in compliance with the License. You may obtain a copy of the // License at http://www.apache.org/licenses/LICENSE-2.0 // Unless required by applicable law or agreed to in writing, software distributed // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR // CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. /// @title Interface RewardManager pragma solidity >=0.7.0 <0.9.0; interface IRewardManager { /// @notice Rewards address /// @param _address address be rewarded /// @param _amount reward /// @dev only the pos contract can call this function reward(address _address, uint256 _amount) external; /// @notice Get RewardManager's balance function getBalance() external view returns (uint256); /// @notice Get current reward amount function getCurrentReward() external view returns (uint256); }
// Copyright 2021 Cartesi Pte. Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); you may not use // this file except in compliance with the License. You may obtain a copy of the // License at http://www.apache.org/licenses/LICENSE-2.0 // Unless required by applicable law or agreed to in writing, software distributed // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR // CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. /// @title Interface Staking pragma solidity >=0.7.0 <0.9.0; interface IStaking { /// @notice Returns total amount of tokens counted as stake /// @param _userAddress user to retrieve staked balance from /// @return finalized staked of _userAddress function getStakedBalance(address _userAddress) external view returns (uint256); /// @notice Returns the timestamp when next deposit can be finalized /// @return timestamp of when finalizeStakes() is callable function getMaturingTimestamp(address _userAddress) external view returns (uint256); /// @notice Returns the timestamp when next withdraw can be finalized /// @return timestamp of when finalizeWithdraw() is callable function getReleasingTimestamp(address _userAddress) external view returns (uint256); /// @notice Returns the balance waiting/ready to be matured /// @return amount that will get staked after finalization function getMaturingBalance(address _userAddress) external view returns (uint256); /// @notice Returns the balance waiting/ready to be released /// @return amount that will get withdrew after finalization function getReleasingBalance(address _userAddress) external view returns (uint256); /// @notice Deposit CTSI to be staked. The money will turn into staked /// balance after timeToStake days /// @param _amount The amount of tokens that are gonna be deposited. function stake(uint256 _amount) external; /// @notice Remove tokens from staked balance. The money can /// be released after timeToRelease seconds, if the /// function withdraw is called. /// @param _amount The amount of tokens that are gonna be unstaked. function unstake(uint256 _amount) external; /// @notice Transfer tokens to user's wallet. /// @param _amount The amount of tokens that are gonna be transferred. function withdraw(uint256 _amount) external; // events /// @notice CTSI tokens were deposited, they count as stake after _maturationDate /// @param user address of msg.sender /// @param amount amount deposited for staking /// @param maturationDate date when the stake can be finalized event Stake(address indexed user, uint256 amount, uint256 maturationDate); /// @notice Unstake tokens, moving them to releasing structure /// @param user address of msg.sender /// @param amount amount of tokens to be released /// @param maturationDate date when the tokens can be withdrew event Unstake(address indexed user, uint256 amount, uint256 maturationDate); /// @notice Withdraw process was finalized /// @param user address of msg.sender /// @param amount amount of tokens withdrawn event Withdraw(address indexed user, uint256 amount); }
// Copyright 2021 Cartesi Pte. Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); you may not use // this file except in compliance with the License. You may obtain a copy of the // License at http://www.apache.org/licenses/LICENSE-2.0 // Unless required by applicable law or agreed to in writing, software distributed // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR // CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. /// @title Interface WorkerManager /// @author Danilo Tuler pragma solidity >=0.7.0 <0.9.0; interface IWorkerManagerAuthManager { /// @notice Asks the worker to work for the sender. Sender needs to pay something. /// @param workerAddress address of the worker function hire(address payable workerAddress) external payable; /// @notice Called by the user to cancel a job offer /// @param workerAddress address of the worker node function cancelHire(address workerAddress) external; /// @notice Called by the user to retire his worker. /// @param workerAddress address of the worker to be retired /// @dev this also removes all authorizations in place function retire(address payable workerAddress) external; /// @notice Gives worker permission to act on a DApp /// @param _workerAddress address of the worker node to given permission /// @param _dappAddress address of the dapp that permission will be given to function authorize(address _workerAddress, address _dappAddress) external; /// @notice Called by the worker to accept the job function acceptJob() external; /// @notice Called by the worker to reject a job offer function rejectJob() external payable; }
pragma solidity >=0.8.4; interface ENS { // Logged when the owner of a node assigns a new owner to a subnode. event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner); // Logged when the owner of a node transfers ownership to a new account. event Transfer(bytes32 indexed node, address owner); // Logged when the resolver for a node changes. event NewResolver(bytes32 indexed node, address resolver); // Logged when the TTL of a node changes event NewTTL(bytes32 indexed node, uint64 ttl); // Logged when an operator is added or removed. event ApprovalForAll(address indexed owner, address indexed operator, bool approved); function setRecord(bytes32 node, address owner, address resolver, uint64 ttl) external virtual; function setSubnodeRecord(bytes32 node, bytes32 label, address owner, address resolver, uint64 ttl) external virtual; function setSubnodeOwner(bytes32 node, bytes32 label, address owner) external virtual returns(bytes32); function setResolver(bytes32 node, address resolver) external virtual; function setOwner(bytes32 node, address owner) external virtual; function setTTL(bytes32 node, uint64 ttl) external virtual; function setApprovalForAll(address operator, bool approved) external virtual; function owner(bytes32 node) external virtual view returns (address); function resolver(bytes32 node) external virtual view returns (address); function ttl(bytes32 node) external virtual view returns (uint64); function recordExists(bytes32 node) external virtual view returns (bool); function isApprovedForAll(address owner, address operator) external virtual view returns (bool); }
pragma solidity >=0.8.4; import "./ENS.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "../root/Controllable.sol"; abstract contract NameResolver { function setName(bytes32 node, string memory name) public virtual; } bytes32 constant lookup = 0x3031323334353637383961626364656600000000000000000000000000000000; bytes32 constant ADDR_REVERSE_NODE = 0x91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e2; // namehash('addr.reverse') contract ReverseRegistrar is Ownable, Controllable { ENS public ens; NameResolver public defaultResolver; event ReverseClaimed(address indexed addr, bytes32 indexed node); /** * @dev Constructor * @param ensAddr The address of the ENS registry. * @param resolverAddr The address of the default reverse resolver. */ constructor(ENS ensAddr, NameResolver resolverAddr) { ens = ensAddr; defaultResolver = resolverAddr; // Assign ownership of the reverse record to our deployer ReverseRegistrar oldRegistrar = ReverseRegistrar( ens.owner(ADDR_REVERSE_NODE) ); if (address(oldRegistrar) != address(0x0)) { oldRegistrar.claim(msg.sender); } } modifier authorised(address addr) { require( addr == msg.sender || controllers[msg.sender] || ens.isApprovedForAll(addr, msg.sender) || ownsContract(addr), "Caller is not a controller or authorised by address or the address itself" ); _; } /** * @dev Transfers ownership of the reverse ENS record associated with the * calling account. * @param owner The address to set as the owner of the reverse record in ENS. * @return The ENS node hash of the reverse record. */ function claim(address owner) public returns (bytes32) { return _claimWithResolver(msg.sender, owner, address(0x0)); } /** * @dev Transfers ownership of the reverse ENS record associated with the * calling account. * @param addr The reverse record to set * @param owner The address to set as the owner of the reverse record in ENS. * @return The ENS node hash of the reverse record. */ function claimForAddr(address addr, address owner) public authorised(addr) returns (bytes32) { return _claimWithResolver(addr, owner, address(0x0)); } /** * @dev Transfers ownership of the reverse ENS record associated with the * calling account. * @param owner The address to set as the owner of the reverse record in ENS. * @param resolver The address of the resolver to set; 0 to leave unchanged. * @return The ENS node hash of the reverse record. */ function claimWithResolver(address owner, address resolver) public returns (bytes32) { return _claimWithResolver(msg.sender, owner, resolver); } /** * @dev Transfers ownership of the reverse ENS record specified with the * address provided * @param addr The reverse record to set * @param owner The address to set as the owner of the reverse record in ENS. * @param resolver The address of the resolver to set; 0 to leave unchanged. * @return The ENS node hash of the reverse record. */ function claimWithResolverForAddr( address addr, address owner, address resolver ) public authorised(addr) returns (bytes32) { return _claimWithResolver(addr, owner, resolver); } /** * @dev Sets the `name()` record for the reverse ENS record associated with * the calling account. First updates the resolver to the default reverse * resolver if necessary. * @param name The name to set for this address. * @return The ENS node hash of the reverse record. */ function setName(string memory name) public returns (bytes32) { bytes32 node = _claimWithResolver( msg.sender, address(this), address(defaultResolver) ); defaultResolver.setName(node, name); return node; } /** * @dev Sets the `name()` record for the reverse ENS record associated with * the account provided. First updates the resolver to the default reverse * resolver if necessary. * Only callable by controllers and authorised users * @param addr The reverse record to set * @param owner The owner of the reverse node * @param name The name to set for this address. * @return The ENS node hash of the reverse record. */ function setNameForAddr( address addr, address owner, string memory name ) public authorised(addr) returns (bytes32) { bytes32 node = _claimWithResolver( addr, address(this), address(defaultResolver) ); defaultResolver.setName(node, name); ens.setSubnodeOwner(ADDR_REVERSE_NODE, sha3HexAddress(addr), owner); return node; } /** * @dev Returns the node hash for a given account's reverse records. * @param addr The address to hash * @return The ENS node hash. */ function node(address addr) public pure returns (bytes32) { return keccak256( abi.encodePacked(ADDR_REVERSE_NODE, sha3HexAddress(addr)) ); } /** * @dev An optimised function to compute the sha3 of the lower-case * hexadecimal representation of an Ethereum address. * @param addr The address to hash * @return ret The SHA3 hash of the lower-case hexadecimal encoding of the * input address. */ function sha3HexAddress(address addr) private pure returns (bytes32 ret) { assembly { for { let i := 40 } gt(i, 0) { } { i := sub(i, 1) mstore8(i, byte(and(addr, 0xf), lookup)) addr := div(addr, 0x10) i := sub(i, 1) mstore8(i, byte(and(addr, 0xf), lookup)) addr := div(addr, 0x10) } ret := keccak256(0, 40) } } /* Internal functions */ function _claimWithResolver( address addr, address owner, address resolver ) internal returns (bytes32) { bytes32 label = sha3HexAddress(addr); bytes32 node = keccak256(abi.encodePacked(ADDR_REVERSE_NODE, label)); address currentResolver = ens.resolver(node); bool shouldUpdateResolver = (resolver != address(0x0) && resolver != currentResolver); address newResolver = shouldUpdateResolver ? resolver : currentResolver; ens.setSubnodeRecord(ADDR_REVERSE_NODE, label, owner, newResolver, 0); emit ReverseClaimed(addr, node); return node; } function ownsContract(address addr) internal view returns (bool) { try Ownable(addr).owner() returns (address owner) { return owner == msg.sender; } catch { return false; } } }
pragma solidity ^0.8.4; import "@openzeppelin/contracts/access/Ownable.sol"; contract Controllable is Ownable { mapping(address => bool) public controllers; event ControllerChanged(address indexed controller, bool enabled); modifier onlyController { require( controllers[msg.sender], "Controllable: Caller is not a controller" ); _; } function setController(address controller, bool enabled) public onlyOwner { controllers[controller] = enabled; emit ControllerChanged(controller, enabled); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../utils/ContextUpgradeable.sol"; import "../proxy/utils/Initializable.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function __Ownable_init() internal initializer { __Context_init_unchained(); __Ownable_init_unchained(); } function __Ownable_init_unchained() internal initializer { _setOwner(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _setOwner(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _setOwner(newOwner); } function _setOwner(address newOwner) private { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } uint256[49] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @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. */ 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() { require(_initializing || !_initialized, "Initializable: contract is already initialized"); bool isTopLevelCall = !_initializing; if (isTopLevelCall) { _initializing = true; _initialized = true; } _; if (isTopLevelCall) { _initializing = false; } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../utils/ContextUpgradeable.sol"; import "../proxy/utils/Initializable.sol"; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract PausableUpgradeable is Initializable, ContextUpgradeable { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ function __Pausable_init() internal initializer { __Context_init_unchained(); __Pausable_init_unchained(); } function __Pausable_init_unchained() internal initializer { _paused = false; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { require(!paused(), "Pausable: paused"); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { require(paused(), "Pausable: not paused"); _; } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } uint256[49] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../proxy/utils/Initializable.sol"; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract ContextUpgradeable is Initializable { function __Context_init() internal initializer { __Context_init_unchained(); } function __Context_init_unchained() internal initializer { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } uint256[50] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _setOwner(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _setOwner(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _setOwner(newOwner); } function _setOwner(address newOwner) private { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// Copyright 2021 Cartesi Pte. Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); you may not use // this file except in compliance with the License. You may obtain a copy of the // License at http://www.apache.org/licenses/LICENSE-2.0 // Unless required by applicable law or agreed to in writing, software distributed // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR // CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. pragma solidity ^0.8.0; import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@cartesi/pos/contracts/IPoS.sol"; import "./utils/WadRayMath.sol"; contract StakingPoolData is Initializable, PausableUpgradeable, OwnableUpgradeable { using WadRayMath for uint256; uint256 public shares; // total number of shares uint256 public amount; // amount of staked tokens (no matter where it is) uint256 public requiredLiquidity; // amount of required tokens for withdraw requests IPoS public pos; struct UserBalance { uint256 balance; // amount of free tokens belonging to this user uint256 shares; // amount of shares belonging to this user uint256 depositTimestamp; // timestamp of when user deposited for the last time } mapping(address => UserBalance) public userBalance; function amountToShares(uint256 _amount) public view returns (uint256) { if (amount == 0) { // no shares yet, return 1 to 1 ratio return _amount.wad2ray(); } return _amount.wmul(shares).wdiv(amount); } function sharesToAmount(uint256 _shares) public view returns (uint256) { if (shares == 0) { // no shares yet, return 1 to 1 ratio return _shares.ray2wad(); } return _shares.rmul(amount).rdiv(shares); } }
// Copyright 2021 Cartesi Pte. Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); you may not use // this file except in compliance with the License. You may obtain a copy of the // License at http://www.apache.org/licenses/LICENSE-2.0 // Unless required by applicable law or agreed to in writing, software distributed // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR // CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. pragma solidity ^0.8.0; import "@ensdomains/ens-contracts/contracts/registry/ReverseRegistrar.sol"; import "@ensdomains/ens-contracts/contracts/registry/ENS.sol"; import "./interfaces/StakingPoolManagement.sol"; import "./interfaces/StakingPoolFactory.sol"; import "./StakingPoolData.sol"; contract StakingPoolManagementImpl is StakingPoolManagement, StakingPoolData { bytes32 private constant ADDR_REVERSE_NODE = 0x91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e2; ENS public immutable ens; StakingPoolFactory public factory; // all immutable variables can stay at the constructor constructor(address _ens) initializer { require(_ens != address(0), "parameter can not be zero address"); ens = ENS(_ens); // make sure reference code is pause so no one stake to it _pause(); } function __StakingPoolManagementImpl_init() internal { factory = StakingPoolFactory(msg.sender); } /// @notice sets a name for the pool using ENS service function setName(string memory name) external override onlyOwner { ReverseRegistrar ensReverseRegistrar = ReverseRegistrar( ens.owner(ADDR_REVERSE_NODE) ); // call the ENS reverse registrar resolving pool address to name ensReverseRegistrar.setName(name); // emit event, for subgraph processing emit StakingPoolRenamed(name); } /// @notice pauses new staking on the pool function pause() external override onlyOwner { _pause(); } /// @notice unpauses new staking on the pool function unpause() external override onlyOwner { _unpause(); } }
// Copyright 2021 Cartesi Pte. Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); you may not use // this file except in compliance with the License. You may obtain a copy of the // License at http://www.apache.org/licenses/LICENSE-2.0 // Unless required by applicable law or agreed to in writing, software distributed // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR // CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@cartesi/pos/contracts/IPoS.sol"; import "@cartesi/pos/contracts/IRewardManager.sol"; import "./interfaces/Fee.sol"; import "./interfaces/StakingPoolProducer.sol"; import "./StakingPoolData.sol"; contract StakingPoolProducerImpl is StakingPoolProducer, StakingPoolData { IERC20 public immutable ctsi; Fee public fee; constructor(address _ctsi) { ctsi = IERC20(_ctsi); } function __StakingPoolProducer_init(address _fee, address _pos) internal { fee = Fee(_fee); pos = IPoS(_pos); } /// @notice routes produceBlock to POS contract and /// updates internal states of the pool /// @return true when everything went fine function produceBlock(uint256 _index) external override returns (bool) { IRewardManager rewardManager = IRewardManager( pos.getRewardManagerAddress(_index) ); // get block reward uint256 reward = rewardManager.getCurrentReward(); // produce block in the PoS require( pos.produceBlock(_index), "StakingPoolProducerImpl: failed to produce block" ); // calculate pool commission uint256 commission = fee.getCommission(_index, reward); require( commission <= reward, "StakingPoolProducerImpl: commission is greater than block reward" ); uint256 remainingReward = reward - commission; // this is a safety check // if commission is over the reward amount, it will underflow // increase pool amount, this will change the pool exchange rate amount += remainingReward; // send commission directly to pool owner if (commission > 0) { require( ctsi.transfer(owner(), commission), "StakingPoolProducerImpl: failed to transfer commission" ); } // remainingReward is part of the balance, so it will automatically be staked by StakingPoolStakingImpl emit BlockProduced(reward, commission); return true; } }
// Copyright 2021 Cartesi Pte. Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); you may not use // this file except in compliance with the License. You may obtain a copy of the // License at http://www.apache.org/licenses/LICENSE-2.0 // Unless required by applicable law or agreed to in writing, software distributed // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR // CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@cartesi/pos/contracts/IStaking.sol"; import "./interfaces/StakingPoolStaking.sol"; import "./StakingPoolData.sol"; /// @notice This contract takes care of the interaction between the pool and the staking contract /// It makes sure that there is enough liquidity in the pool to fullfil all unstake request from /// users, by requesting to withdraw or unstake from Staking contract. /// The remaining balance is staked. contract StakingPoolStakingImpl is StakingPoolStaking, StakingPoolData { IERC20 private immutable ctsi; IStaking private immutable staking; constructor(address _ctsi, address _staking) { ctsi = IERC20(_ctsi); staking = IStaking(_staking); } function __StakingPoolStaking_init() internal { require( ctsi.approve(address(staking), type(uint256).max), "Failed to approve CTSI for staking contract" ); } function rebalance() external override { // get amounts (uint256 _stake, uint256 _unstake, uint256 _withdraw) = amounts(); if (_stake > 0) { // we can stake staking.stake(_stake); } if (_unstake > 0) { // we need to provide liquidity staking.unstake(_unstake); } if (_withdraw > 0) { // we need to provide liquidity staking.withdraw(_withdraw); } } function amounts() public view override returns ( uint256 stake, uint256 unstake, uint256 withdraw ) { // get this contract balance first uint256 balance = ctsi.balanceOf(address(this)); if (balance > requiredLiquidity) { // we have spare tokens we can stake // check if there is anything already maturing, to avoid reset the maturation clock uint256 maturing = staking.getMaturingBalance(address(this)); if (maturing == 0) { // nothing is maturing, we can stake the balance, preserving the liquidity stake = balance - requiredLiquidity; } } else if (requiredLiquidity > balance) { // we don't have enough tokens to provide liquidity uint256 missingLiquidity = requiredLiquidity - balance; // let's first check releasing balance uint256 releasing = staking.getReleasingBalance(address(this)); if (releasing > 0) { // some is already releasing // let's check timestamp to see if we can withdrawn it uint256 timestamp = staking.getReleasingTimestamp( address(this) ); if (timestamp < block.timestamp) { // there it is, let's grab it withdraw = releasing; } // requiredLiquidity may be more than what is already releasing // but we won't unstake more to not reset the clock } else { // no unstake maturing, let's queue some unstake = missingLiquidity; } } else { // balance is exactly required liquidity, we can't move any tokens around } } }
// Copyright 2021 Cartesi Pte. Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); you may not use // this file except in compliance with the License. You may obtain a copy of the // License at http://www.apache.org/licenses/LICENSE-2.0 // Unless required by applicable law or agreed to in writing, software distributed // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR // CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "./interfaces/StakingPoolUser.sol"; import "./StakingPoolData.sol"; contract StakingPoolUserImpl is StakingPoolUser, StakingPoolData { IERC20 private immutable ctsi; uint256 public immutable lockTime; /// @dev Constructor /// @param _ctsi The contract that provides the staking pool's token /// @param _lockTime The user deposit lock period constructor(address _ctsi, uint256 _lockTime) { ctsi = IERC20(_ctsi); lockTime = _lockTime; } function deposit(uint256 _amount) external override whenNotPaused { // transfer tokens from caller to this contract // user must have approved the transfer a priori // tokens will be lying around, until actually staked by pool owner at a later time require( _amount > 0, "StakingPoolUserImpl: amount must be greater than 0" ); // add tokens to user's balance UserBalance storage user = userBalance[msg.sender]; user.balance += _amount; // reset deposit timestamp user.depositTimestamp = block.timestamp; // reserve the balance as required liquidity (don't stake to Staking) requiredLiquidity += _amount; require( ctsi.transferFrom(msg.sender, address(this), _amount), "StakingPoolUserImpl: failed to transfer tokens" ); // emit event containing user and amount emit Deposit(msg.sender, _amount, block.timestamp + lockTime); } /// @notice Stake an amount of tokens, immediately earning pool shares in returns /// @param _amount amount of tokens to convert from user's balance function stake(uint256 _amount) external override whenNotPaused { // get user balance UserBalance storage user = userBalance[msg.sender]; // transfer tokens from caller to this contract // user must have approved the transfer a priori // tokens will be lying around, until actually staked by pool owner at a later time require( _amount > 0, "StakingPoolUserImpl: amount must be greater than 0" ); require( _amount <= user.balance, "StakingPoolUserImpl: not enough tokens available for staking" ); // check if user can already stake or if it's too early require( block.timestamp >= user.depositTimestamp + lockTime, "StakingPoolUserImpl: not enough time has passed since last deposit" ); // calculate amount of shares as of now uint256 _shares = amountToShares(_amount); // make sure he get at least one share (rounding errors) require( _shares > 0, "StakingPoolUserImpl: stake not enough to emit 1 share" ); // allocate new shares to user, immediately user.shares += _shares; user.balance -= _amount; // increase total shares and amount (not changing share value) amount += _amount; shares += _shares; // remove from required liquidity, as it's moving to Staking requiredLiquidity -= _amount; // emit event containing user, amount, shares and unlock time emit Stake(msg.sender, _amount, _shares); } /// @notice allow for users to defined exactly how many shares they /// want to unstake. Estimated value is then emitted on Unstake event function unstake(uint256 _shares) external override { UserBalance storage user = userBalance[msg.sender]; // check if shares is valid value require(_shares > 0, "StakingPoolUserImpl: invalid amount of shares"); // check if user has enough shares to unstake require( user.shares >= _shares, "StakingPoolUserImpl: insufficient shares" ); // reduce user number of shares user.shares -= _shares; // calculate amount of tokens from shares uint256 _amount = sharesToAmount(_shares); // reduce total shares and amount shares -= _shares; amount -= _amount; // add amount user can withdraw (if available) user.balance += _amount; // increase required liquidity requiredLiquidity += _amount; // emit event containing user, amount and shares emit Unstake(msg.sender, _amount, _shares); } /// @notice Transfer tokens back to calling user wallet /// @dev this will transfer all free tokens for the calling user function withdraw(uint256 _amount) external override { UserBalance storage user = userBalance[msg.sender]; // check user released value require( user.balance > 0, "StakingPoolUserImpl: no balance to withdraw" ); // clear user released value user.balance -= _amount; // if _amount > user.balance this will revert // decrease required liquidity requiredLiquidity -= _amount; // if _amount > requiredLiquidity this will revert // transfer token back to user require( ctsi.transfer(msg.sender, _amount), "StakingPoolUserImpl: failed to transfer tokens" ); // emit event containing user and token amount emit Withdraw(msg.sender, _amount); } function getWithdrawBalance() external view override returns (uint256) { UserBalance storage user = userBalance[msg.sender]; // get maximum amount user can withdraw (his balance) uint256 _amount = user.balance; // check contract balance uint256 balance = ctsi.balanceOf(address(this)); // he can withdraw whatever is available at the contract, up to his balance return balance >= _amount ? _amount : balance; } }
// Copyright 2021 Cartesi Pte. Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); you may not use // this file except in compliance with the License. You may obtain a copy of the // License at http://www.apache.org/licenses/LICENSE-2.0 // Unless required by applicable law or agreed to in writing, software distributed // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR // CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. pragma solidity ^0.8.0; import "@cartesi/pos/contracts/IWorkerManagerAuthManager.sol"; import "./interfaces/StakingPoolWorker.sol"; import "./StakingPoolData.sol"; contract StakingPoolWorkerImpl is StakingPoolWorker, StakingPoolData { IWorkerManagerAuthManager immutable workerManager; // all immutable variables can stay at the constructor constructor(address _workerManager) { require( _workerManager != address(0), "parameter can not be zero address" ); workerManager = IWorkerManagerAuthManager(_workerManager); } receive() external payable {} function __StakingPoolWorkerImpl_update(address _pos) internal { workerManager.authorize(address(this), _pos); pos = IPoS(_pos); } /// @notice allows for the pool to act on its own behalf when producing blocks. function selfhire() external payable override { // pool needs to be both user and worker workerManager.hire{value: msg.value}(payable(address(this))); workerManager.authorize(address(this), address(pos)); workerManager.acceptJob(); payable(msg.sender).transfer(msg.value); } /// @notice Asks the worker to work for the sender. Sender needs to pay something. /// @param workerAddress address of the worker function hire(address payable workerAddress) external payable override onlyOwner { workerManager.hire{value: msg.value}(workerAddress); workerManager.authorize(workerAddress, address(pos)); } /// @notice Called by the user to cancel a job offer /// @param workerAddress address of the worker node function cancelHire(address workerAddress) external override onlyOwner { workerManager.cancelHire(workerAddress); } /// @notice Called by the user to retire his worker. /// @param workerAddress address of the worker to be retired /// @dev this also removes all authorizations in place function retire(address payable workerAddress) external override onlyOwner { workerManager.retire(workerAddress); } }
// Copyright 2021 Cartesi Pte. Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); you may not use // this file except in compliance with the License. You may obtain a copy of the // License at http://www.apache.org/licenses/LICENSE-2.0 // Unless required by applicable law or agreed to in writing, software distributed // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR // CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. pragma solidity >=0.7.0 <0.9.0; /// @title Calculator of pool owner commission for each block reward /// @author Danilo Tuler /// @notice This provides flexibility for different commission models interface Fee { /// @notice calculates the total amount of the reward that will be directed to the pool owner /// @return amount of tokens taken by the pool owner as commission function getCommission(uint256 posIndex, uint256 rewardAmount) external view returns (uint256); }
// Copyright 2021 Cartesi Pte. Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); you may not use // this file except in compliance with the License. You may obtain a copy of the // License at http://www.apache.org/licenses/LICENSE-2.0 // Unless required by applicable law or agreed to in writing, software distributed // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR // CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. pragma solidity >=0.7.0; import "./StakingPoolManagement.sol"; import "./StakingPoolProducer.sol"; import "./StakingPoolStaking.sol"; import "./StakingPoolUser.sol"; import "./StakingPoolWorker.sol"; /// @title Staking Pool interface /// @author Danilo Tuler /// @notice This interface aggregates all facets of a staking pool. /// It is broken down into the following sub-interfaces: /// - StakingPoolManagement: management operations on the pool, called by the owner /// - StakingPoolProducer: operations related to block production /// - StakingPoolStaking: interaction between the pool and the staking contract /// - StakingPoolUser: interaction between the pool users and the pool /// - StakingPoolWorker: interaction between the pool and the worker node interface StakingPool is StakingPoolManagement, StakingPoolProducer, StakingPoolStaking, StakingPoolUser, StakingPoolWorker { /// @notice initialize pool (from reference) function initialize(address fee, address _pos) external; /// @notice Transfer ownership of pool to its deployer function transferOwnership(address newOwner) external; /// @notice updates the internal settings for important pieces of the Cartesi PoS system function update() external; }
// Copyright 2021 Cartesi Pte. Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); you may not use // this file except in compliance with the License. You may obtain a copy of the // License at http://www.apache.org/licenses/LICENSE-2.0 // Unless required by applicable law or agreed to in writing, software distributed // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR // CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. pragma solidity >=0.7.0; interface StakingPoolFactory { /// @notice Creates a new staking pool using a flat commission model /// emits NewFlatRateCommissionStakingPool with the parameters of the new pool /// @return new pool address function createFlatRateCommission(uint256 commission) external payable returns (address); /// @notice Creates a new staking pool using a gas tax commission model /// emits NewGasTaxCommissionStakingPool with the parameters of the new pool /// @return new pool address function createGasTaxCommission(uint256 gas) external payable returns (address); /// @notice Returns configuration for the working pools of the current version /// @return _pos address for the PoS contract function getPoS() external view returns (address _pos); /// @notice Event emmited when a pool is created /// @param pool address of the new pool /// @param fee address of the commission contract event NewFlatRateCommissionStakingPool(address indexed pool, address fee); /// @notice Event emmited when a pool is created /// @param pool address of the new pool /// @param fee address of thhe commission contract event NewGasTaxCommissionStakingPool(address indexed pool, address fee); }
// Copyright 2021 Cartesi Pte. Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); you may not use // this file except in compliance with the License. You may obtain a copy of the // License at http://www.apache.org/licenses/LICENSE-2.0 // Unless required by applicable law or agreed to in writing, software distributed // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR // CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. pragma solidity >=0.7.0; interface StakingPoolManagement { /// @notice sets a name for the pool using ENS service function setName(string memory name) external; /// @notice pauses new staking on the pool function pause() external; /// @notice unpauses new staking on the pool function unpause() external; /// @notice Event emmited when a pool is rename event StakingPoolRenamed(string name); }
// Copyright 2021 Cartesi Pte. Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); you may not use // this file except in compliance with the License. You may obtain a copy of the // License at http://www.apache.org/licenses/LICENSE-2.0 // Unless required by applicable law or agreed to in writing, software distributed // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR // CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. pragma solidity >=0.7.0; /// @title Interaction between a pool and the PoS block production. /// @author Danilo Tuler /// @notice This interface provides an opportunity to handle the necessary logic /// after a block is produced. /// A commission is taken from the block reward, and the remaining stays in the pool, /// raising the pool share value, and being further staked. interface StakingPoolProducer { /// @notice routes produceBlock to POS contract and /// updates internal states of the pool /// @return true when everything went fine function produceBlock(uint256 _index) external returns (bool); /// @notice this event is emitted at every produceBlock call /// reward is the block reward /// commission is how much CTSI is directed to the pool owner event BlockProduced(uint256 reward, uint256 commission); }
// Copyright 2021 Cartesi Pte. Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); you may not use // this file except in compliance with the License. You may obtain a copy of the // License at http://www.apache.org/licenses/LICENSE-2.0 // Unless required by applicable law or agreed to in writing, software distributed // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR // CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. pragma solidity >=0.7.0; /// @title Interaction between a pool and the staking contract /// @author Danilo Tuler /// @notice This interface models all interactions between a pool and the staking contract, /// including staking, unstaking and withdrawing. /// Tokens staked by pool users will stay at the pool until the pool owner decides to /// stake them in the staking contract. On the other hand, tokens unstaked by pool users /// are added to a required liquidity accumulator, and must be unstaked and withdrawn from /// the staking contract. interface StakingPoolStaking { /// @notice Move tokens from pool to staking or vice-versa, according to required liquidity. /// If the pool has more liquidity then necessary, it stakes tokens. /// If the pool has less liquidity then necessary, and has not started an unstake, it unstakes. /// If the pool has less liquity than necessary, and has started an unstake, it withdraws if possible. function rebalance() external; /// @notice provide information for offchain about the amount for each /// staking operation on the main Staking contract /// @return stake amount of tokens that can be staked /// @return unstake amount of tokens that must be unstaked to add liquidity /// @return withdraw amount of tokens that can be withdrawn to add liquidity function amounts() external view returns ( uint256 stake, uint256 unstake, uint256 withdraw ); }
// Copyright 2021 Cartesi Pte. Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); you may not use // this file except in compliance with the License. You may obtain a copy of the // License at http://www.apache.org/licenses/LICENSE-2.0 // Unless required by applicable law or agreed to in writing, software distributed // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR // CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. pragma solidity >=0.7.0; /// @title Interaction between a pool user and a pool /// @author Danilo Tuler /// @notice This interface models all interactions between a pool user and a pool, /// including staking, unstaking and withdrawing. A pool user always holds pool shares. /// When a user stakes tokens, he immediately receive shares. When he unstakes shares /// he is asking to release tokens. Those tokens need to be withdrawn by an additional /// call to withdraw() interface StakingPoolUser { /// @notice Deposit tokens to user pool balance /// @param amount amount of token deposited in the pool function deposit(uint256 amount) external; /// @notice Stake an amount of tokens, immediately earning pool shares in returns /// @param amount amount of tokens to convert to shares function stake(uint256 amount) external; /// @notice Unstake an specified amount of shares of the calling user /// @dev Shares are immediately converted to tokens, and added to the pool liquidity requirement function unstake(uint256 shares) external; /// @notice Transfer tokens back to calling user wallet /// @dev this will transfer tokens from user pool account to user's wallet function withdraw(uint256 amount) external; /// @notice Returns the amount of tokens that can be immediately withdrawn by the calling user /// @dev there is no way to know the exact time in the future the requested tokens will be available /// @return the amount of tokens that can be immediately withdrawn by the calling user function getWithdrawBalance() external returns (uint256); /// @notice Tokens were deposited, available for staking or withdrawal /// @param user address of msg.sender /// @param amount amount of tokens deposited by the user /// @param stakeTimestamp instant when the amount can be staked event Deposit(address indexed user, uint256 amount, uint256 stakeTimestamp); /// @notice Tokens were deposited, they count as shares immediatly /// @param user address of msg.sender /// @param amount amount deposited by the user /// @param shares number of shares emitted for user event Stake(address indexed user, uint256 amount, uint256 shares); /// @notice Request to unstake tokens. Additional liquidity requested for the pool /// @param user address of msg.sender /// @param amount amount of tokens to be released /// @param shares number of shares being liquidated event Unstake(address indexed user, uint256 amount, uint256 shares); /// @notice Withdraw performed by a user /// @param user address of msg.sender /// @param amount amount of tokens withdrawn event Withdraw(address indexed user, uint256 amount); }
// Copyright 2021 Cartesi Pte. Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); you may not use // this file except in compliance with the License. You may obtain a copy of the // License at http://www.apache.org/licenses/LICENSE-2.0 // Unless required by applicable law or agreed to in writing, software distributed // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR // CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. pragma solidity >=0.7.0; interface StakingPoolWorker { /// @notice allows for the pool to act on its own behalf when producing blocks. function selfhire() external payable; /// @notice Asks the worker to work for the sender. Sender needs to pay something. /// @param workerAddress address of the worker function hire(address payable workerAddress) external payable; /// @notice Called by the user to cancel a job offer /// @param workerAddress address of the worker node function cancelHire(address workerAddress) external; /// @notice Called by the user to retire his worker. /// @param workerAddress address of the worker to be retired /// @dev this also removes all authorizations in place function retire(address payable workerAddress) external; }
// Copyright 2021 Cartesi Pte. Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); you may not use // this file except in compliance with the License. You may obtain a copy of the // License at http://www.apache.org/licenses/LICENSE-2.0 // Unless required by applicable law or agreed to in writing, software distributed // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR // CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. /// @title Wad and Ray Math library /// @dev Math operations for wads (fixed point with 18 digits) and rays (fixed points with 27 digits) pragma solidity ^0.8.0; library WadRayMath { uint256 internal constant WAD = 1e18; uint256 internal constant RAY = 1e27; uint256 internal constant RATIO = 1e9; function wmul(uint256 a, uint256 b) internal pure returns (uint256) { return ((WAD / 2) + (a * b)) / WAD; } function wdiv(uint256 a, uint256 b) internal pure returns (uint256) { uint256 halfB = b / 2; return (halfB + (a * WAD)) / b; } function rmul(uint256 a, uint256 b) internal pure returns (uint256) { return ((RAY / 2) + (a * b)) / RAY; } function rdiv(uint256 a, uint256 b) internal pure returns (uint256) { uint256 halfB = b / 2; return (halfB + (a * RAY)) / b; } function ray2wad(uint256 a) internal pure returns (uint256) { uint256 halfRatio = RATIO / 2; return (halfRatio + a) / RATIO; } function wad2ray(uint256 a) internal pure returns (uint256) { return a * RATIO; } }
{ "evmVersion": "london", "libraries": {}, "metadata": { "bytecodeHash": "ipfs", "useLiteralContent": true }, "optimizer": { "enabled": true, "runs": 200 }, "remappings": [], "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } } }
[{"inputs":[{"internalType":"address","name":"_ctsi","type":"address"},{"internalType":"address","name":"_staking","type":"address"},{"internalType":"address","name":"_workerManager","type":"address"},{"internalType":"address","name":"_ens","type":"address"},{"internalType":"uint256","name":"_stakeLock","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"commission","type":"uint256"}],"name":"BlockProduced","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stakeTimestamp","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"Stake","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"name","type":"string"}],"name":"StakingPoolRenamed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"Unstake","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"amount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"amountToShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"amounts","outputs":[{"internalType":"uint256","name":"stake","type":"uint256"},{"internalType":"uint256","name":"unstake","type":"uint256"},{"internalType":"uint256","name":"withdraw","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"workerAddress","type":"address"}],"name":"cancelHire","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"ctsi","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"ens","outputs":[{"internalType":"contract ENS","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"contract StakingPoolFactory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fee","outputs":[{"internalType":"contract Fee","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getWithdrawBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address payable","name":"workerAddress","type":"address"}],"name":"hire","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_fee","type":"address"},{"internalType":"address","name":"_pos","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lockTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pos","outputs":[{"internalType":"contract IPoS","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"produceBlock","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rebalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"requiredLiquidity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address payable","name":"workerAddress","type":"address"}],"name":"retire","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"selfhire","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"}],"name":"setName","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"shares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_shares","type":"uint256"}],"name":"sharesToAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_shares","type":"uint256"}],"name":"unstake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"update","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userBalance","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"uint256","name":"depositTimestamp","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | 100.00% | $0.198977 | 14,591.2296 | $2,903.31 |
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.