Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
Value | ||||
---|---|---|---|---|---|---|---|---|---|
0x61016060 | 13305578 | 1016 days ago | IN | Create: StakingPoolImpl | 0 ETH | 0.17877232 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
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" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"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"}]
Contract Creation Code
6101606040523480156200001257600080fd5b5060405162002e8538038062002e858339810160408190526200003591620002c1565b82858287878987600060019054906101000a900460ff16806200005b575060005460ff16155b620000c45760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b600054610100900460ff16158015620000e7576000805461ffff19166101011790555b6001600160a01b038216620001385760405162461bcd60e51b8152602060048201526021602482015260008051602062002e658339815191526044820152607360f81b6064820152608401620000bb565b6001600160601b0319606083901b166080526200015462000209565b801562000167576000805461ff00191690555b50506001600160601b0319606091821b811660a05292811b831660c05290811b821660e0529290921b90911661010052610120526001600160a01b038116620001ec5760405162461bcd60e51b8152602060048201526021602482015260008051602062002e658339815191526044820152607360f81b6064820152608401620000bb565b60601b6001600160601b0319166101405250620003289350505050565b60335460ff1615620002515760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401620000bb565b6033805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258620002873390565b6040516001600160a01b03909116815260200160405180910390a1565b80516001600160a01b0381168114620002bc57600080fd5b919050565b600080600080600060a08688031215620002da57600080fd5b620002e586620002a4565b9450620002f560208701620002a4565b93506200030560408701620002a4565b92506200031560608701620002a4565b9150608086015190509295509295909350565b60805160601c60a05160601c60c05160601c60e05160601c6101005160601c610120516101405160601c612a446200042160003960008181610da201528181610e2d01528181610e910152818161124301528181611ab801528181611eb701528181611f3c0152612392015260008181610290015281816118910152611c5c01526000818161089501528181610f650152611b94015260008181610b7401528181610c5001528181610cea0152818161105d015281816110de0152818161115f0152612106015260008181610ad601526121360152600081816103cb015261165a0152600081816103060152611d2f0152612a446000f3fe6080604052600436106101f25760003560e01c80638456cb591161010d578063b6b55f25116100a0578063c56551b61161006f578063c56551b6146105a7578063d9d6bd86146105c7578063ddca3f43146105da578063e366b7bb146105fa578063f2fde38b1461061057600080fd5b8063b6b55f2514610527578063b811540e14610547578063c45a015514610567578063c47f00271461058757600080fd5b8063a5a6cd0b116100dc578063a5a6cd0b146104b1578063a694fc3a146104d1578063aa8c217c146104f1578063b64b3bed1461050757600080fd5b80638456cb59146104495780638da5cb5b1461045e5780639e6371ba1461047c578063a2e620451461049c57600080fd5b8063555d8ebb116101855780636ff46a6c116101545780636ff46a6c14610402578063710fe6f81461040a578063715018a61461041f5780637d7c2a1c1461043457600080fd5b8063555d8ebb146103755780635c975abb1461039557806364ffc3f4146103b95780636beaeeae146103ed57600080fd5b80632e1a7d4d116101c15780632e1a7d4d146102d45780633f15457f146102f45780633f4ba83a14610340578063485cc9551461035557600080fd5b80630103c92b146101fe57806303314efa1461025a5780630d6680871461027e5780632e17de78146102b257600080fd5b366101f957005b600080fd5b34801561020a57600080fd5b5061023a610219366004612643565b609b6020526000908152604090208054600182015460029092015490919083565b604080519384526020840192909252908201526060015b60405180910390f35b34801561026657600080fd5b5061027060975481565b604051908152602001610251565b34801561028a57600080fd5b506102707f000000000000000000000000000000000000000000000000000000000000000081565b3480156102be57600080fd5b506102d26102cd3660046127a2565b610630565b005b3480156102e057600080fd5b506102d26102ef3660046127a2565b6107d6565b34801561030057600080fd5b506103287f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610251565b34801561034c57600080fd5b506102d261096f565b34801561036157600080fd5b506102d261037036600461267d565b6109a3565b34801561038157600080fd5b506102706103903660046127a2565b610a73565b3480156103a157600080fd5b5060335460ff165b6040519015158152602001610251565b3480156103c557600080fd5b506103287f000000000000000000000000000000000000000000000000000000000000000081565b3480156103f957600080fd5b5061023a610ab0565b6102d2610d8d565b34801561041657600080fd5b50610270610f32565b34801561042b57600080fd5b506102d2610ff9565b34801561044057600080fd5b506102d261102d565b34801561045557600080fd5b506102d26111c8565b34801561046a57600080fd5b506065546001600160a01b0316610328565b34801561048857600080fd5b506102d2610497366004612643565b6111fa565b3480156104a857600080fd5b506102d26112a3565b3480156104bd57600080fd5b506103a96104cc3660046127a2565b611355565b3480156104dd57600080fd5b506102d26104ec3660046127a2565b6117c9565b3480156104fd57600080fd5b5061027060985481565b34801561051357600080fd5b506102d2610522366004612643565b611a6f565b34801561053357600080fd5b506102d26105423660046127a2565b611ae7565b34801561055357600080fd5b506102706105623660046127a2565b611c96565b34801561057357600080fd5b50609c54610328906001600160a01b031681565b34801561059357600080fd5b506102d26105a23660046126f1565b611ccd565b3480156105b357600080fd5b50609a54610328906001600160a01b031681565b6102d26105d5366004612643565b611e6e565b3480156105e657600080fd5b50609d54610328906001600160a01b031681565b34801561060657600080fd5b5061027060995481565b34801561061c57600080fd5b506102d261062b366004612643565b611f71565b336000908152609b60205260409020816106a75760405162461bcd60e51b815260206004820152602d60248201527f5374616b696e67506f6f6c55736572496d706c3a20696e76616c696420616d6f60448201526c756e74206f662073686172657360981b60648201526084015b60405180910390fd5b818160010154101561070c5760405162461bcd60e51b815260206004820152602860248201527f5374616b696e67506f6f6c55736572496d706c3a20696e73756666696369656e604482015267742073686172657360c01b606482015260840161069e565b8181600101600082825461072091906129b6565b909155506000905061073183610a73565b9050826097600082825461074591906129b6565b92505081905550806098600082825461075e91906129b6565b909155505081548190839060009061077790849061295d565b925050819055508060996000828254610790919061295d565b9091555050604080518281526020810185905233917ff960dbf9e5d0682f7a298ed974e33a28b4464914b7a2bfac12ae419a9afeb28091015b60405180910390a2505050565b336000908152609b6020526040902080546108475760405162461bcd60e51b815260206004820152602b60248201527f5374616b696e67506f6f6c55736572496d706c3a206e6f2062616c616e63652060448201526a746f20776974686472617760a81b606482015260840161069e565b8181600001600082825461085b91906129b6565b92505081905550816099600082825461087491906129b6565b909155505060405163a9059cbb60e01b8152336004820152602481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a9059cbb90604401602060405180830381600087803b1580156108e157600080fd5b505af11580156108f5573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061091991906126b6565b6109355760405162461bcd60e51b815260040161069e90612810565b60405182815233907f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a9424364906020015b60405180910390a25050565b6065546001600160a01b031633146109995760405162461bcd60e51b815260040161069e906128d6565b6109a1611f7a565b565b600054610100900460ff16806109bc575060005460ff16155b6109d85760405162461bcd60e51b815260040161069e90612888565b600054610100900460ff161580156109fa576000805461ffff19166101011790555b610a0261200d565b610a0a612088565b610a3d8383609d80546001600160a01b039384166001600160a01b031991821617909155609a8054929093169116179055565b610a456120ef565b610a5c609c80546001600160a01b03191633179055565b8015610a6e576000805461ff00191690555b505050565b600060975460001415610a8f57610a8982612212565b92915050565b610a89609754610aaa6098548561224690919063ffffffff16565b90612280565b6040516370a0823160e01b81523060048201526000908190819081906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a082319060240160206040518083038186803b158015610b1857600080fd5b505afa158015610b2c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b5091906126d8565b9050609954811115610c1357604051631066f98960e21b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063419be6249060240160206040518083038186803b158015610bbe57600080fd5b505afa158015610bd2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bf691906126d8565b905080610c0d57609954610c0a90836129b6565b94505b50610d87565b806099541115610d8757600081609954610c2d91906129b6565b604051638e9f04b560e01b81523060048201529091506000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690638e9f04b59060240160206040518083038186803b158015610c9257600080fd5b505afa158015610ca6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cca91906126d8565b90508015610d80576040516367ba9b9160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906367ba9b919060240160206040518083038186803b158015610d3457600080fd5b505afa158015610d48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d6c91906126d8565b905042811015610d7a578194505b50610d84565b8194505b50505b50909192565b604051636ceb5ec360e11b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063d9d6bd869034906024016000604051808303818588803b158015610def57600080fd5b505af1158015610e03573d6000803e3d6000fd5b5050609a54604051632bef459560e01b81523060048201526001600160a01b0391821660248201527f00000000000000000000000000000000000000000000000000000000000000009091169350632bef459592506044019050600060405180830381600087803b158015610e7757600080fd5b505af1158015610e8b573d6000803e3d6000fd5b505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639b789b7e6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610eea57600080fd5b505af1158015610efe573d6000803e3d6000fd5b50506040513392503480156108fc029250906000818181858888f19350505050158015610f2f573d6000803e3d6000fd5b50565b336000908152609b6020526040808220805491516370a0823160e01b815230600482015290919083906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a082319060240160206040518083038186803b158015610fa757600080fd5b505afa158015610fbb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fdf91906126d8565b905081811015610fef5780610ff1565b815b935050505090565b6065546001600160a01b031633146110235760405162461bcd60e51b815260040161069e906128d6565b6109a160006122c3565b600080600061103a610ab0565b9194509250905082156110c25760405163534a7e1d60e11b8152600481018490527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a694fc3a90602401600060405180830381600087803b1580156110a957600080fd5b505af11580156110bd573d6000803e3d6000fd5b505050505b8115611143576040516305c2fbcf60e31b8152600481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632e17de7890602401600060405180830381600087803b15801561112a57600080fd5b505af115801561113e573d6000803e3d6000fd5b505050505b8015610a6e57604051632e1a7d4d60e01b8152600481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632e1a7d4d90602401600060405180830381600087803b1580156111ab57600080fd5b505af11580156111bf573d6000803e3d6000fd5b50505050505050565b6065546001600160a01b031633146111f25760405162461bcd60e51b815260040161069e906128d6565b6109a1612315565b6065546001600160a01b031633146112245760405162461bcd60e51b815260040161069e906128d6565b604051634f31b8dd60e11b81526001600160a01b0382811660048301527f00000000000000000000000000000000000000000000000000000000000000001690639e6371ba906024015b600060405180830381600087803b15801561128857600080fd5b505af115801561129c573d6000803e3d6000fd5b5050505050565b6065546001600160a01b031633146112cd5760405162461bcd60e51b815260040161069e906128d6565b609c5460408051632686e29d60e01b815290516000926001600160a01b031691632686e29d916004808301926020929190829003018186803b15801561131257600080fd5b505afa158015611326573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061134a9190612660565b9050610f2f8161236d565b609a546040516385425f4f60e01b81526004810183905260009182916001600160a01b03909116906385425f4f9060240160206040518083038186803b15801561139e57600080fd5b505afa1580156113b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113d69190612660565b90506000816001600160a01b0316638aec85426040518163ffffffff1660e01b815260040160206040518083038186803b15801561141357600080fd5b505afa158015611427573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061144b91906126d8565b609a5460405163a5a6cd0b60e01b8152600481018790529192506001600160a01b03169063a5a6cd0b90602401602060405180830381600087803b15801561149257600080fd5b505af11580156114a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114ca91906126b6565b61152f5760405162461bcd60e51b815260206004820152603060248201527f5374616b696e67506f6f6c50726f6475636572496d706c3a206661696c65642060448201526f746f2070726f6475636520626c6f636b60801b606482015260840161069e565b609d54604051632c7f22b560e21b815260048101869052602481018390526000916001600160a01b03169063b1fc8ad49060440160206040518083038186803b15801561157b57600080fd5b505afa15801561158f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115b391906126d8565b90508181111561162d576040805162461bcd60e51b81526020600482015260248101919091527f5374616b696e67506f6f6c50726f6475636572496d706c3a20636f6d6d69737360448201527f696f6e2069732067726561746572207468616e20626c6f636b20726577617264606482015260840161069e565b600061163982846129b6565b9050806098600082825461164d919061295d565b90915550508115611784577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb6116996065546001600160a01b031690565b6040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260248101859052604401602060405180830381600087803b1580156116e157600080fd5b505af11580156116f5573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061171991906126b6565b6117845760405162461bcd60e51b815260206004820152603660248201527f5374616b696e67506f6f6c50726f6475636572496d706c3a206661696c6564206044820152753a37903a3930b739b332b91031b7b6b6b4b9b9b4b7b760511b606482015260840161069e565b60408051848152602081018490527fbb9ac692e0e3001a628f86a894f03da4ced5df81886fec577036664ed70a59cb910160405180910390a150600195945050505050565b60335460ff16156117ec5760405162461bcd60e51b815260040161069e9061285e565b336000908152609b60205260409020816118185760405162461bcd60e51b815260040161069e9061290b565b805482111561188f5760405162461bcd60e51b815260206004820152603c60248201527f5374616b696e67506f6f6c55736572496d706c3a206e6f7420656e6f7567682060448201527f746f6b656e7320617661696c61626c6520666f72207374616b696e6700000000606482015260840161069e565b7f000000000000000000000000000000000000000000000000000000000000000081600201546118bf919061295d565b42101561193f5760405162461bcd60e51b815260206004820152604260248201527f5374616b696e67506f6f6c55736572496d706c3a206e6f7420656e6f7567682060448201527f74696d6520686173207061737365642073696e6365206c617374206465706f736064820152611a5d60f21b608482015260a40161069e565b600061194a83611c96565b9050600081116119ba5760405162461bcd60e51b815260206004820152603560248201527f5374616b696e67506f6f6c55736572496d706c3a207374616b65206e6f7420656044820152746e6f75676820746f20656d6974203120736861726560581b606482015260840161069e565b808260010160008282546119ce919061295d565b90915550508154839083906000906119e79084906129b6565b925050819055508260986000828254611a00919061295d565b925050819055508060976000828254611a19919061295d565b925050819055508260996000828254611a3291906129b6565b9091555050604080518481526020810183905233917f5af417134f72a9d41143ace85b0a26dce6f550f894f2cbc1eeee8810603d91b691016107c9565b6065546001600160a01b03163314611a995760405162461bcd60e51b815260040161069e906128d6565b60405163b64b3bed60e01b81526001600160a01b0382811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063b64b3bed9060240161126e565b60335460ff1615611b0a5760405162461bcd60e51b815260040161069e9061285e565b60008111611b2a5760405162461bcd60e51b815260040161069e9061290b565b336000908152609b60205260408120805490918391839190611b4d90849061295d565b909155505042600282015560998054839190600090611b6d90849061295d565b90915550506040516323b872dd60e01b8152336004820152306024820152604481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906323b872dd90606401602060405180830381600087803b158015611be057600080fd5b505af1158015611bf4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c1891906126b6565b611c345760405162461bcd60e51b815260040161069e90612810565b337f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a1583611c817f00000000000000000000000000000000000000000000000000000000000000004261295d565b60408051928352602083019190915201610963565b600060985460001415611cac57610a8982612411565b610a89609854611cc76097548561242190919063ffffffff16565b90612449565b6065546001600160a01b03163314611cf75760405162461bcd60e51b815260040161069e906128d6565b6040516302571be360e01b81527f91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e260048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906302571be39060240160206040518083038186803b158015611d7957600080fd5b505afa158015611d8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611db19190612660565b60405163c47f002760e01b81529091506001600160a01b0382169063c47f002790611de09085906004016127bb565b602060405180830381600087803b158015611dfa57600080fd5b505af1158015611e0e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e3291906126d8565b507f6aaa0865532d48a9a0f63cc91df7ff2ab538c896665c864ae02d0a1e7f81cf6582604051611e6291906127bb565b60405180910390a15050565b6065546001600160a01b03163314611e985760405162461bcd60e51b815260040161069e906128d6565b604051636ceb5ec360e11b81526001600160a01b0382811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063d9d6bd869034906024016000604051808303818588803b158015611efc57600080fd5b505af1158015611f10573d6000803e3d6000fd5b5050609a54604051632bef459560e01b81526001600160a01b03868116600483015291821660248201527f00000000000000000000000000000000000000000000000000000000000000009091169350632bef45959250604401905061126e565b610f2f8161246c565b60335460ff16611fc35760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015260640161069e565b6033805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b600054610100900460ff1680612026575060005460ff16155b6120425760405162461bcd60e51b815260040161069e90612888565b600054610100900460ff16158015612064576000805461ffff19166101011790555b61206c612504565b61207461256e565b8015610f2f576000805461ff001916905550565b600054610100900460ff16806120a1575060005460ff16155b6120bd5760405162461bcd60e51b815260040161069e90612888565b600054610100900460ff161580156120df576000805461ffff19166101011790555b6120e7612504565b6120746125e3565b60405163095ea7b360e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116600483015260001960248301527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b390604401602060405180830381600087803b15801561217a57600080fd5b505af115801561218e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121b291906126b6565b6109a15760405162461bcd60e51b815260206004820152602b60248201527f4661696c656420746f20617070726f7665204354534920666f72207374616b6960448201526a1b99c818dbdb9d1c9858dd60aa1b606482015260840161069e565b6000806122246002633b9aca00612975565b9050633b9aca00612235848361295d565b61223f9190612975565b9392505050565b60006b033b2e3c9fd0803ce800000061225f8385612997565b61227660026b033b2e3c9fd0803ce8000000612975565b612235919061295d565b60008061228e600284612975565b9050826122a76b033b2e3c9fd0803ce800000086612997565b6122b1908361295d565b6122bb9190612975565b949350505050565b606580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60335460ff16156123385760405162461bcd60e51b815260040161069e9061285e565b6033805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611ff03390565b604051632bef459560e01b81523060048201526001600160a01b0382811660248301527f00000000000000000000000000000000000000000000000000000000000000001690632bef459590604401600060405180830381600087803b1580156123d657600080fd5b505af11580156123ea573d6000803e3d6000fd5b5050609a80546001600160a01b0319166001600160a01b0394909416939093179092555050565b6000610a89633b9aca0083612997565b6000670de0b6b3a76400006124368385612997565b6122766002670de0b6b3a7640000612975565b600080612457600284612975565b9050826122a7670de0b6b3a764000086612997565b6065546001600160a01b031633146124965760405162461bcd60e51b815260040161069e906128d6565b6001600160a01b0381166124fb5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161069e565b610f2f816122c3565b600054610100900460ff168061251d575060005460ff16155b6125395760405162461bcd60e51b815260040161069e90612888565b600054610100900460ff16158015612074576000805461ffff19166101011790558015610f2f576000805461ff001916905550565b600054610100900460ff1680612587575060005460ff16155b6125a35760405162461bcd60e51b815260040161069e90612888565b600054610100900460ff161580156125c5576000805461ffff19166101011790555b6033805460ff191690558015610f2f576000805461ff001916905550565b600054610100900460ff16806125fc575060005460ff16155b6126185760405162461bcd60e51b815260040161069e90612888565b600054610100900460ff1615801561263a576000805461ffff19166101011790555b612074336122c3565b60006020828403121561265557600080fd5b813561223f816129f9565b60006020828403121561267257600080fd5b815161223f816129f9565b6000806040838503121561269057600080fd5b823561269b816129f9565b915060208301356126ab816129f9565b809150509250929050565b6000602082840312156126c857600080fd5b8151801515811461223f57600080fd5b6000602082840312156126ea57600080fd5b5051919050565b60006020828403121561270357600080fd5b813567ffffffffffffffff8082111561271b57600080fd5b818401915084601f83011261272f57600080fd5b813581811115612741576127416129e3565b604051601f8201601f19908116603f01168101908382118183101715612769576127696129e3565b8160405282815287602084870101111561278257600080fd5b826020860160208301376000928101602001929092525095945050505050565b6000602082840312156127b457600080fd5b5035919050565b600060208083528351808285015260005b818110156127e8578581018301518582016040015282016127cc565b818111156127fa576000604083870101525b50601f01601f1916929092016040019392505050565b6020808252602e908201527f5374616b696e67506f6f6c55736572496d706c3a206661696c656420746f207460408201526d72616e7366657220746f6b656e7360901b606082015260800190565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526032908201527f5374616b696e67506f6f6c55736572496d706c3a20616d6f756e74206d75737460408201527102062652067726561746572207468616e20360741b606082015260800190565b60008219821115612970576129706129cd565b500190565b60008261299257634e487b7160e01b600052601260045260246000fd5b500490565b60008160001904831182151516156129b1576129b16129cd565b500290565b6000828210156129c8576129c86129cd565b500390565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610f2f57600080fdfea26469706673582212203c535d95c790ec68bcf07e0f09fa1de8d9ac93b9383ffe05946507faa4e6d27064736f6c63430008070033706172616d657465722063616e206e6f74206265207a65726f20616464726573000000000000000000000000491604c0fdf08347dd1fa4ee062a822a5dd06b5d0000000000000000000000009edeadfde65bcfd0907db3acdb3445229c764a69000000000000000000000000832d9f06970ddac7ba49be5a2ccad8f89df74c1300000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e0000000000000000000000000000000000000000000000000000000000005460
Deployed Bytecode
0x6080604052600436106101f25760003560e01c80638456cb591161010d578063b6b55f25116100a0578063c56551b61161006f578063c56551b6146105a7578063d9d6bd86146105c7578063ddca3f43146105da578063e366b7bb146105fa578063f2fde38b1461061057600080fd5b8063b6b55f2514610527578063b811540e14610547578063c45a015514610567578063c47f00271461058757600080fd5b8063a5a6cd0b116100dc578063a5a6cd0b146104b1578063a694fc3a146104d1578063aa8c217c146104f1578063b64b3bed1461050757600080fd5b80638456cb59146104495780638da5cb5b1461045e5780639e6371ba1461047c578063a2e620451461049c57600080fd5b8063555d8ebb116101855780636ff46a6c116101545780636ff46a6c14610402578063710fe6f81461040a578063715018a61461041f5780637d7c2a1c1461043457600080fd5b8063555d8ebb146103755780635c975abb1461039557806364ffc3f4146103b95780636beaeeae146103ed57600080fd5b80632e1a7d4d116101c15780632e1a7d4d146102d45780633f15457f146102f45780633f4ba83a14610340578063485cc9551461035557600080fd5b80630103c92b146101fe57806303314efa1461025a5780630d6680871461027e5780632e17de78146102b257600080fd5b366101f957005b600080fd5b34801561020a57600080fd5b5061023a610219366004612643565b609b6020526000908152604090208054600182015460029092015490919083565b604080519384526020840192909252908201526060015b60405180910390f35b34801561026657600080fd5b5061027060975481565b604051908152602001610251565b34801561028a57600080fd5b506102707f000000000000000000000000000000000000000000000000000000000000546081565b3480156102be57600080fd5b506102d26102cd3660046127a2565b610630565b005b3480156102e057600080fd5b506102d26102ef3660046127a2565b6107d6565b34801561030057600080fd5b506103287f00000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e81565b6040516001600160a01b039091168152602001610251565b34801561034c57600080fd5b506102d261096f565b34801561036157600080fd5b506102d261037036600461267d565b6109a3565b34801561038157600080fd5b506102706103903660046127a2565b610a73565b3480156103a157600080fd5b5060335460ff165b6040519015158152602001610251565b3480156103c557600080fd5b506103287f000000000000000000000000491604c0fdf08347dd1fa4ee062a822a5dd06b5d81565b3480156103f957600080fd5b5061023a610ab0565b6102d2610d8d565b34801561041657600080fd5b50610270610f32565b34801561042b57600080fd5b506102d2610ff9565b34801561044057600080fd5b506102d261102d565b34801561045557600080fd5b506102d26111c8565b34801561046a57600080fd5b506065546001600160a01b0316610328565b34801561048857600080fd5b506102d2610497366004612643565b6111fa565b3480156104a857600080fd5b506102d26112a3565b3480156104bd57600080fd5b506103a96104cc3660046127a2565b611355565b3480156104dd57600080fd5b506102d26104ec3660046127a2565b6117c9565b3480156104fd57600080fd5b5061027060985481565b34801561051357600080fd5b506102d2610522366004612643565b611a6f565b34801561053357600080fd5b506102d26105423660046127a2565b611ae7565b34801561055357600080fd5b506102706105623660046127a2565b611c96565b34801561057357600080fd5b50609c54610328906001600160a01b031681565b34801561059357600080fd5b506102d26105a23660046126f1565b611ccd565b3480156105b357600080fd5b50609a54610328906001600160a01b031681565b6102d26105d5366004612643565b611e6e565b3480156105e657600080fd5b50609d54610328906001600160a01b031681565b34801561060657600080fd5b5061027060995481565b34801561061c57600080fd5b506102d261062b366004612643565b611f71565b336000908152609b60205260409020816106a75760405162461bcd60e51b815260206004820152602d60248201527f5374616b696e67506f6f6c55736572496d706c3a20696e76616c696420616d6f60448201526c756e74206f662073686172657360981b60648201526084015b60405180910390fd5b818160010154101561070c5760405162461bcd60e51b815260206004820152602860248201527f5374616b696e67506f6f6c55736572496d706c3a20696e73756666696369656e604482015267742073686172657360c01b606482015260840161069e565b8181600101600082825461072091906129b6565b909155506000905061073183610a73565b9050826097600082825461074591906129b6565b92505081905550806098600082825461075e91906129b6565b909155505081548190839060009061077790849061295d565b925050819055508060996000828254610790919061295d565b9091555050604080518281526020810185905233917ff960dbf9e5d0682f7a298ed974e33a28b4464914b7a2bfac12ae419a9afeb28091015b60405180910390a2505050565b336000908152609b6020526040902080546108475760405162461bcd60e51b815260206004820152602b60248201527f5374616b696e67506f6f6c55736572496d706c3a206e6f2062616c616e63652060448201526a746f20776974686472617760a81b606482015260840161069e565b8181600001600082825461085b91906129b6565b92505081905550816099600082825461087491906129b6565b909155505060405163a9059cbb60e01b8152336004820152602481018390527f000000000000000000000000491604c0fdf08347dd1fa4ee062a822a5dd06b5d6001600160a01b03169063a9059cbb90604401602060405180830381600087803b1580156108e157600080fd5b505af11580156108f5573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061091991906126b6565b6109355760405162461bcd60e51b815260040161069e90612810565b60405182815233907f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a9424364906020015b60405180910390a25050565b6065546001600160a01b031633146109995760405162461bcd60e51b815260040161069e906128d6565b6109a1611f7a565b565b600054610100900460ff16806109bc575060005460ff16155b6109d85760405162461bcd60e51b815260040161069e90612888565b600054610100900460ff161580156109fa576000805461ffff19166101011790555b610a0261200d565b610a0a612088565b610a3d8383609d80546001600160a01b039384166001600160a01b031991821617909155609a8054929093169116179055565b610a456120ef565b610a5c609c80546001600160a01b03191633179055565b8015610a6e576000805461ff00191690555b505050565b600060975460001415610a8f57610a8982612212565b92915050565b610a89609754610aaa6098548561224690919063ffffffff16565b90612280565b6040516370a0823160e01b81523060048201526000908190819081906001600160a01b037f000000000000000000000000491604c0fdf08347dd1fa4ee062a822a5dd06b5d16906370a082319060240160206040518083038186803b158015610b1857600080fd5b505afa158015610b2c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b5091906126d8565b9050609954811115610c1357604051631066f98960e21b81523060048201526000907f0000000000000000000000009edeadfde65bcfd0907db3acdb3445229c764a696001600160a01b03169063419be6249060240160206040518083038186803b158015610bbe57600080fd5b505afa158015610bd2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bf691906126d8565b905080610c0d57609954610c0a90836129b6565b94505b50610d87565b806099541115610d8757600081609954610c2d91906129b6565b604051638e9f04b560e01b81523060048201529091506000906001600160a01b037f0000000000000000000000009edeadfde65bcfd0907db3acdb3445229c764a691690638e9f04b59060240160206040518083038186803b158015610c9257600080fd5b505afa158015610ca6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cca91906126d8565b90508015610d80576040516367ba9b9160e01b81523060048201526000907f0000000000000000000000009edeadfde65bcfd0907db3acdb3445229c764a696001600160a01b0316906367ba9b919060240160206040518083038186803b158015610d3457600080fd5b505afa158015610d48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d6c91906126d8565b905042811015610d7a578194505b50610d84565b8194505b50505b50909192565b604051636ceb5ec360e11b81523060048201527f000000000000000000000000832d9f06970ddac7ba49be5a2ccad8f89df74c136001600160a01b03169063d9d6bd869034906024016000604051808303818588803b158015610def57600080fd5b505af1158015610e03573d6000803e3d6000fd5b5050609a54604051632bef459560e01b81523060048201526001600160a01b0391821660248201527f000000000000000000000000832d9f06970ddac7ba49be5a2ccad8f89df74c139091169350632bef459592506044019050600060405180830381600087803b158015610e7757600080fd5b505af1158015610e8b573d6000803e3d6000fd5b505050507f000000000000000000000000832d9f06970ddac7ba49be5a2ccad8f89df74c136001600160a01b0316639b789b7e6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610eea57600080fd5b505af1158015610efe573d6000803e3d6000fd5b50506040513392503480156108fc029250906000818181858888f19350505050158015610f2f573d6000803e3d6000fd5b50565b336000908152609b6020526040808220805491516370a0823160e01b815230600482015290919083906001600160a01b037f000000000000000000000000491604c0fdf08347dd1fa4ee062a822a5dd06b5d16906370a082319060240160206040518083038186803b158015610fa757600080fd5b505afa158015610fbb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fdf91906126d8565b905081811015610fef5780610ff1565b815b935050505090565b6065546001600160a01b031633146110235760405162461bcd60e51b815260040161069e906128d6565b6109a160006122c3565b600080600061103a610ab0565b9194509250905082156110c25760405163534a7e1d60e11b8152600481018490527f0000000000000000000000009edeadfde65bcfd0907db3acdb3445229c764a696001600160a01b03169063a694fc3a90602401600060405180830381600087803b1580156110a957600080fd5b505af11580156110bd573d6000803e3d6000fd5b505050505b8115611143576040516305c2fbcf60e31b8152600481018390527f0000000000000000000000009edeadfde65bcfd0907db3acdb3445229c764a696001600160a01b031690632e17de7890602401600060405180830381600087803b15801561112a57600080fd5b505af115801561113e573d6000803e3d6000fd5b505050505b8015610a6e57604051632e1a7d4d60e01b8152600481018290527f0000000000000000000000009edeadfde65bcfd0907db3acdb3445229c764a696001600160a01b031690632e1a7d4d90602401600060405180830381600087803b1580156111ab57600080fd5b505af11580156111bf573d6000803e3d6000fd5b50505050505050565b6065546001600160a01b031633146111f25760405162461bcd60e51b815260040161069e906128d6565b6109a1612315565b6065546001600160a01b031633146112245760405162461bcd60e51b815260040161069e906128d6565b604051634f31b8dd60e11b81526001600160a01b0382811660048301527f000000000000000000000000832d9f06970ddac7ba49be5a2ccad8f89df74c131690639e6371ba906024015b600060405180830381600087803b15801561128857600080fd5b505af115801561129c573d6000803e3d6000fd5b5050505050565b6065546001600160a01b031633146112cd5760405162461bcd60e51b815260040161069e906128d6565b609c5460408051632686e29d60e01b815290516000926001600160a01b031691632686e29d916004808301926020929190829003018186803b15801561131257600080fd5b505afa158015611326573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061134a9190612660565b9050610f2f8161236d565b609a546040516385425f4f60e01b81526004810183905260009182916001600160a01b03909116906385425f4f9060240160206040518083038186803b15801561139e57600080fd5b505afa1580156113b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113d69190612660565b90506000816001600160a01b0316638aec85426040518163ffffffff1660e01b815260040160206040518083038186803b15801561141357600080fd5b505afa158015611427573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061144b91906126d8565b609a5460405163a5a6cd0b60e01b8152600481018790529192506001600160a01b03169063a5a6cd0b90602401602060405180830381600087803b15801561149257600080fd5b505af11580156114a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114ca91906126b6565b61152f5760405162461bcd60e51b815260206004820152603060248201527f5374616b696e67506f6f6c50726f6475636572496d706c3a206661696c65642060448201526f746f2070726f6475636520626c6f636b60801b606482015260840161069e565b609d54604051632c7f22b560e21b815260048101869052602481018390526000916001600160a01b03169063b1fc8ad49060440160206040518083038186803b15801561157b57600080fd5b505afa15801561158f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115b391906126d8565b90508181111561162d576040805162461bcd60e51b81526020600482015260248101919091527f5374616b696e67506f6f6c50726f6475636572496d706c3a20636f6d6d69737360448201527f696f6e2069732067726561746572207468616e20626c6f636b20726577617264606482015260840161069e565b600061163982846129b6565b9050806098600082825461164d919061295d565b90915550508115611784577f000000000000000000000000491604c0fdf08347dd1fa4ee062a822a5dd06b5d6001600160a01b031663a9059cbb6116996065546001600160a01b031690565b6040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260248101859052604401602060405180830381600087803b1580156116e157600080fd5b505af11580156116f5573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061171991906126b6565b6117845760405162461bcd60e51b815260206004820152603660248201527f5374616b696e67506f6f6c50726f6475636572496d706c3a206661696c6564206044820152753a37903a3930b739b332b91031b7b6b6b4b9b9b4b7b760511b606482015260840161069e565b60408051848152602081018490527fbb9ac692e0e3001a628f86a894f03da4ced5df81886fec577036664ed70a59cb910160405180910390a150600195945050505050565b60335460ff16156117ec5760405162461bcd60e51b815260040161069e9061285e565b336000908152609b60205260409020816118185760405162461bcd60e51b815260040161069e9061290b565b805482111561188f5760405162461bcd60e51b815260206004820152603c60248201527f5374616b696e67506f6f6c55736572496d706c3a206e6f7420656e6f7567682060448201527f746f6b656e7320617661696c61626c6520666f72207374616b696e6700000000606482015260840161069e565b7f000000000000000000000000000000000000000000000000000000000000546081600201546118bf919061295d565b42101561193f5760405162461bcd60e51b815260206004820152604260248201527f5374616b696e67506f6f6c55736572496d706c3a206e6f7420656e6f7567682060448201527f74696d6520686173207061737365642073696e6365206c617374206465706f736064820152611a5d60f21b608482015260a40161069e565b600061194a83611c96565b9050600081116119ba5760405162461bcd60e51b815260206004820152603560248201527f5374616b696e67506f6f6c55736572496d706c3a207374616b65206e6f7420656044820152746e6f75676820746f20656d6974203120736861726560581b606482015260840161069e565b808260010160008282546119ce919061295d565b90915550508154839083906000906119e79084906129b6565b925050819055508260986000828254611a00919061295d565b925050819055508060976000828254611a19919061295d565b925050819055508260996000828254611a3291906129b6565b9091555050604080518481526020810183905233917f5af417134f72a9d41143ace85b0a26dce6f550f894f2cbc1eeee8810603d91b691016107c9565b6065546001600160a01b03163314611a995760405162461bcd60e51b815260040161069e906128d6565b60405163b64b3bed60e01b81526001600160a01b0382811660048301527f000000000000000000000000832d9f06970ddac7ba49be5a2ccad8f89df74c13169063b64b3bed9060240161126e565b60335460ff1615611b0a5760405162461bcd60e51b815260040161069e9061285e565b60008111611b2a5760405162461bcd60e51b815260040161069e9061290b565b336000908152609b60205260408120805490918391839190611b4d90849061295d565b909155505042600282015560998054839190600090611b6d90849061295d565b90915550506040516323b872dd60e01b8152336004820152306024820152604481018390527f000000000000000000000000491604c0fdf08347dd1fa4ee062a822a5dd06b5d6001600160a01b0316906323b872dd90606401602060405180830381600087803b158015611be057600080fd5b505af1158015611bf4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c1891906126b6565b611c345760405162461bcd60e51b815260040161069e90612810565b337f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a1583611c817f00000000000000000000000000000000000000000000000000000000000054604261295d565b60408051928352602083019190915201610963565b600060985460001415611cac57610a8982612411565b610a89609854611cc76097548561242190919063ffffffff16565b90612449565b6065546001600160a01b03163314611cf75760405162461bcd60e51b815260040161069e906128d6565b6040516302571be360e01b81527f91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e260048201526000907f00000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e6001600160a01b0316906302571be39060240160206040518083038186803b158015611d7957600080fd5b505afa158015611d8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611db19190612660565b60405163c47f002760e01b81529091506001600160a01b0382169063c47f002790611de09085906004016127bb565b602060405180830381600087803b158015611dfa57600080fd5b505af1158015611e0e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e3291906126d8565b507f6aaa0865532d48a9a0f63cc91df7ff2ab538c896665c864ae02d0a1e7f81cf6582604051611e6291906127bb565b60405180910390a15050565b6065546001600160a01b03163314611e985760405162461bcd60e51b815260040161069e906128d6565b604051636ceb5ec360e11b81526001600160a01b0382811660048301527f000000000000000000000000832d9f06970ddac7ba49be5a2ccad8f89df74c13169063d9d6bd869034906024016000604051808303818588803b158015611efc57600080fd5b505af1158015611f10573d6000803e3d6000fd5b5050609a54604051632bef459560e01b81526001600160a01b03868116600483015291821660248201527f000000000000000000000000832d9f06970ddac7ba49be5a2ccad8f89df74c139091169350632bef45959250604401905061126e565b610f2f8161246c565b60335460ff16611fc35760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015260640161069e565b6033805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b600054610100900460ff1680612026575060005460ff16155b6120425760405162461bcd60e51b815260040161069e90612888565b600054610100900460ff16158015612064576000805461ffff19166101011790555b61206c612504565b61207461256e565b8015610f2f576000805461ff001916905550565b600054610100900460ff16806120a1575060005460ff16155b6120bd5760405162461bcd60e51b815260040161069e90612888565b600054610100900460ff161580156120df576000805461ffff19166101011790555b6120e7612504565b6120746125e3565b60405163095ea7b360e01b81526001600160a01b037f0000000000000000000000009edeadfde65bcfd0907db3acdb3445229c764a698116600483015260001960248301527f000000000000000000000000491604c0fdf08347dd1fa4ee062a822a5dd06b5d169063095ea7b390604401602060405180830381600087803b15801561217a57600080fd5b505af115801561218e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121b291906126b6565b6109a15760405162461bcd60e51b815260206004820152602b60248201527f4661696c656420746f20617070726f7665204354534920666f72207374616b6960448201526a1b99c818dbdb9d1c9858dd60aa1b606482015260840161069e565b6000806122246002633b9aca00612975565b9050633b9aca00612235848361295d565b61223f9190612975565b9392505050565b60006b033b2e3c9fd0803ce800000061225f8385612997565b61227660026b033b2e3c9fd0803ce8000000612975565b612235919061295d565b60008061228e600284612975565b9050826122a76b033b2e3c9fd0803ce800000086612997565b6122b1908361295d565b6122bb9190612975565b949350505050565b606580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60335460ff16156123385760405162461bcd60e51b815260040161069e9061285e565b6033805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611ff03390565b604051632bef459560e01b81523060048201526001600160a01b0382811660248301527f000000000000000000000000832d9f06970ddac7ba49be5a2ccad8f89df74c131690632bef459590604401600060405180830381600087803b1580156123d657600080fd5b505af11580156123ea573d6000803e3d6000fd5b5050609a80546001600160a01b0319166001600160a01b0394909416939093179092555050565b6000610a89633b9aca0083612997565b6000670de0b6b3a76400006124368385612997565b6122766002670de0b6b3a7640000612975565b600080612457600284612975565b9050826122a7670de0b6b3a764000086612997565b6065546001600160a01b031633146124965760405162461bcd60e51b815260040161069e906128d6565b6001600160a01b0381166124fb5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161069e565b610f2f816122c3565b600054610100900460ff168061251d575060005460ff16155b6125395760405162461bcd60e51b815260040161069e90612888565b600054610100900460ff16158015612074576000805461ffff19166101011790558015610f2f576000805461ff001916905550565b600054610100900460ff1680612587575060005460ff16155b6125a35760405162461bcd60e51b815260040161069e90612888565b600054610100900460ff161580156125c5576000805461ffff19166101011790555b6033805460ff191690558015610f2f576000805461ff001916905550565b600054610100900460ff16806125fc575060005460ff16155b6126185760405162461bcd60e51b815260040161069e90612888565b600054610100900460ff1615801561263a576000805461ffff19166101011790555b612074336122c3565b60006020828403121561265557600080fd5b813561223f816129f9565b60006020828403121561267257600080fd5b815161223f816129f9565b6000806040838503121561269057600080fd5b823561269b816129f9565b915060208301356126ab816129f9565b809150509250929050565b6000602082840312156126c857600080fd5b8151801515811461223f57600080fd5b6000602082840312156126ea57600080fd5b5051919050565b60006020828403121561270357600080fd5b813567ffffffffffffffff8082111561271b57600080fd5b818401915084601f83011261272f57600080fd5b813581811115612741576127416129e3565b604051601f8201601f19908116603f01168101908382118183101715612769576127696129e3565b8160405282815287602084870101111561278257600080fd5b826020860160208301376000928101602001929092525095945050505050565b6000602082840312156127b457600080fd5b5035919050565b600060208083528351808285015260005b818110156127e8578581018301518582016040015282016127cc565b818111156127fa576000604083870101525b50601f01601f1916929092016040019392505050565b6020808252602e908201527f5374616b696e67506f6f6c55736572496d706c3a206661696c656420746f207460408201526d72616e7366657220746f6b656e7360901b606082015260800190565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526032908201527f5374616b696e67506f6f6c55736572496d706c3a20616d6f756e74206d75737460408201527102062652067726561746572207468616e20360741b606082015260800190565b60008219821115612970576129706129cd565b500190565b60008261299257634e487b7160e01b600052601260045260246000fd5b500490565b60008160001904831182151516156129b1576129b16129cd565b500290565b6000828210156129c8576129c86129cd565b500390565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610f2f57600080fdfea26469706673582212203c535d95c790ec68bcf07e0f09fa1de8d9ac93b9383ffe05946507faa4e6d27064736f6c63430008070033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000491604c0fdf08347dd1fa4ee062a822a5dd06b5d0000000000000000000000009edeadfde65bcfd0907db3acdb3445229c764a69000000000000000000000000832d9f06970ddac7ba49be5a2ccad8f89df74c1300000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e0000000000000000000000000000000000000000000000000000000000005460
-----Decoded View---------------
Arg [0] : _ctsi (address): 0x491604c0FDF08347Dd1fa4Ee062a822A5DD06B5D
Arg [1] : _staking (address): 0x9EdEAdFDE65BCfD0907db3AcdB3445229c764A69
Arg [2] : _workerManager (address): 0x832D9f06970ddAc7BA49Be5a2cCad8f89Df74C13
Arg [3] : _ens (address): 0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e
Arg [4] : _stakeLock (uint256): 21600
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 000000000000000000000000491604c0fdf08347dd1fa4ee062a822a5dd06b5d
Arg [1] : 0000000000000000000000009edeadfde65bcfd0907db3acdb3445229c764a69
Arg [2] : 000000000000000000000000832d9f06970ddac7ba49be5a2ccad8f89df74c13
Arg [3] : 00000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e
Arg [4] : 0000000000000000000000000000000000000000000000000000000000005460
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.